@@ -414,7 +414,7 @@ class NavigationDestination extends StatelessWidget {
414
414
/// animation value of 0 is unselected and 1 is selected.
415
415
///
416
416
/// See [NavigationDestination] for an example.
417
- class _NavigationDestinationBuilder extends StatelessWidget {
417
+ class _NavigationDestinationBuilder extends StatefulWidget {
418
418
/// Builds a destination (icon + label) to use in a Material 3 [NavigationBar] .
419
419
const _NavigationDestinationBuilder ({
420
420
required this .buildIcon,
@@ -459,31 +459,34 @@ class _NavigationDestinationBuilder extends StatelessWidget {
459
459
/// Defaults to null, in which case the [label] text will be used.
460
460
final String ? tooltip;
461
461
462
+ @override
463
+ State <_NavigationDestinationBuilder > createState () => _NavigationDestinationBuilderState ();
464
+ }
465
+
466
+ class _NavigationDestinationBuilderState extends State <_NavigationDestinationBuilder > {
467
+ final GlobalKey iconKey = GlobalKey ();
468
+
462
469
@override
463
470
Widget build (BuildContext context) {
464
471
final _NavigationDestinationInfo info = _NavigationDestinationInfo .of (context);
465
472
final NavigationBarThemeData navigationBarTheme = NavigationBarTheme .of (context);
466
473
final NavigationBarThemeData defaults = _defaultsFor (context);
467
- final GlobalKey labelKey = GlobalKey ();
468
474
469
- final bool selected = info.selectedIndex == info.index;
470
475
return _NavigationBarDestinationSemantics (
471
476
child: _NavigationBarDestinationTooltip (
472
- message: tooltip ?? label,
477
+ message: widget. tooltip ?? widget. label,
473
478
child: _IndicatorInkWell (
474
- key: UniqueKey (),
475
- labelKey: labelKey,
479
+ iconKey: iconKey,
476
480
labelBehavior: info.labelBehavior,
477
- selected: selected,
478
481
customBorder: navigationBarTheme.indicatorShape ?? defaults.indicatorShape,
479
482
onTap: info.onTap,
480
483
child: Row (
481
484
children: < Widget > [
482
485
Expanded (
483
486
child: _NavigationBarDestinationLayout (
484
- icon: buildIcon (context),
485
- labelKey : labelKey ,
486
- label: buildLabel (context),
487
+ icon: widget. buildIcon (context),
488
+ iconKey : iconKey ,
489
+ label: widget. buildLabel (context),
487
490
),
488
491
),
489
492
],
@@ -496,10 +499,8 @@ class _NavigationDestinationBuilder extends StatelessWidget {
496
499
497
500
class _IndicatorInkWell extends InkResponse {
498
501
const _IndicatorInkWell ({
499
- super .key,
500
- required this .labelKey,
502
+ required this .iconKey,
501
503
required this .labelBehavior,
502
- required this .selected,
503
504
super .customBorder,
504
505
super .onTap,
505
506
super .child,
@@ -508,32 +509,15 @@ class _IndicatorInkWell extends InkResponse {
508
509
highlightColor: Colors .transparent,
509
510
);
510
511
511
- final GlobalKey labelKey ;
512
+ final GlobalKey iconKey ;
512
513
final NavigationDestinationLabelBehavior labelBehavior;
513
- final bool selected;
514
514
515
515
@override
516
516
RectCallback ? getRectCallback (RenderBox referenceBox) {
517
- final RenderBox labelBox = labelKey.currentContext! .findRenderObject ()! as RenderBox ;
518
- final Rect labelRect = labelBox.localToGlobal (Offset .zero) & labelBox.size;
519
- final double labelPadding;
520
- switch (labelBehavior) {
521
- case NavigationDestinationLabelBehavior .alwaysShow:
522
- labelPadding = labelRect.height / 2 ;
523
- case NavigationDestinationLabelBehavior .onlyShowSelected:
524
- labelPadding = selected ? labelRect.height / 2 : 0 ;
525
- case NavigationDestinationLabelBehavior .alwaysHide:
526
- labelPadding = 0 ;
527
- }
528
- final double indicatorOffsetX = referenceBox.size.width / 2 ;
529
- final double indicatorOffsetY = referenceBox.size.height / 2 - labelPadding;
530
-
531
517
return () {
532
- return Rect .fromCenter (
533
- center: Offset (indicatorOffsetX, indicatorOffsetY),
534
- width: _kIndicatorWidth,
535
- height: _kIndicatorHeight,
536
- );
518
+ final RenderBox iconBox = iconKey.currentContext! .findRenderObject ()! as RenderBox ;
519
+ final Rect iconRect = iconBox.localToGlobal (Offset .zero) & iconBox.size;
520
+ return referenceBox.globalToLocal (iconRect.topLeft) & iconBox.size;
537
521
};
538
522
}
539
523
}
@@ -774,7 +758,7 @@ class _NavigationBarDestinationLayout extends StatelessWidget {
774
758
/// 3 [NavigationBar] .
775
759
const _NavigationBarDestinationLayout ({
776
760
required this .icon,
777
- required this .labelKey ,
761
+ required this .iconKey ,
778
762
required this .label,
779
763
});
780
764
@@ -783,10 +767,10 @@ class _NavigationBarDestinationLayout extends StatelessWidget {
783
767
/// See [NavigationDestination.icon] .
784
768
final Widget icon;
785
769
786
- /// The global key for the label of this destination.
770
+ /// The global key for the icon of this destination.
787
771
///
788
- /// This is used to determine the position of the label relative to the icon.
789
- final GlobalKey labelKey ;
772
+ /// This is used to determine the position of the icon.
773
+ final GlobalKey iconKey ;
790
774
791
775
/// The label widget that sits below the icon.
792
776
///
@@ -796,7 +780,7 @@ class _NavigationBarDestinationLayout extends StatelessWidget {
796
780
/// See [NavigationDestination.label] .
797
781
final Widget label;
798
782
799
- static final Key _iconKey = UniqueKey ();
783
+ static final Key _labelKey = UniqueKey ();
800
784
801
785
@override
802
786
Widget build (BuildContext context) {
@@ -810,7 +794,7 @@ class _NavigationBarDestinationLayout extends StatelessWidget {
810
794
LayoutId (
811
795
id: _NavigationDestinationLayoutDelegate .iconId,
812
796
child: RepaintBoundary (
813
- key: _iconKey ,
797
+ key: iconKey ,
814
798
child: icon,
815
799
),
816
800
),
@@ -820,7 +804,7 @@ class _NavigationBarDestinationLayout extends StatelessWidget {
820
804
alwaysIncludeSemantics: true ,
821
805
opacity: animation,
822
806
child: RepaintBoundary (
823
- key: labelKey ,
807
+ key: _labelKey ,
824
808
child: label,
825
809
),
826
810
),
0 commit comments