Skip to content

Commit 0b3ba80

Browse files
authored
Revert "Fix NavigationBar indicator overlay color (#164484)" (#169497)
## Description This PR reverts the change from [Fix NavigationBar indicator overlay color](#164484) as it leads to several regressions. The change was very small: replacing a Container (which obscured the overlay) with an Ink. Unfortunately this leads to some rendering issues which seem related to the Ink painting not being fully in sync with the animation logic implemented by `NavigationIndicator`. I investigated this but did not find an obvious solution. So I would prefer to revert #164484 as the issue it fixed has less impact than the regression. cc @justinmc for review and also in case you have some clue about why an Ink would cause such problems compared to a Container. ## Related Issue Fixes [[Flutter 3.32.0] Active NavigationBar item not selected when switching items programmatically](#169249) Fixes [NavigationDrawer active indicator offset with SvgPicture](#169436) Fixes #164484 (comment) Reopens #163871
1 parent 8b22f67 commit 0b3ba80

File tree

7 files changed

+52
-35
lines changed

7 files changed

+52
-35
lines changed

packages/flutter/lib/src/material/navigation_bar.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import 'package:flutter/widgets.dart';
1616
import 'color_scheme.dart';
1717
import 'colors.dart';
1818
import 'elevation_overlay.dart';
19-
import 'ink_decoration.dart';
2019
import 'ink_well.dart';
2120
import 'material.dart';
2221
import 'material_localizations.dart';
@@ -869,7 +868,7 @@ class NavigationIndicator extends StatelessWidget {
869868
builder: (BuildContext context, Animation<double> fadeAnimation) {
870869
return FadeTransition(
871870
opacity: fadeAnimation,
872-
child: Ink(
871+
child: Container(
873872
width: width,
874873
height: height,
875874
decoration: ShapeDecoration(

packages/flutter/test/material/navigation_bar_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,8 +1716,8 @@ Material _getMaterial(WidgetTester tester) {
17161716

17171717
ShapeDecoration? _getIndicatorDecoration(WidgetTester tester) {
17181718
return tester
1719-
.firstWidget<Ink>(
1720-
find.descendant(of: find.byType(FadeTransition), matching: find.byType(Ink)),
1719+
.firstWidget<Container>(
1720+
find.descendant(of: find.byType(FadeTransition), matching: find.byType(Container)),
17211721
)
17221722
.decoration
17231723
as ShapeDecoration?;

packages/flutter/test/material/navigation_bar_theme_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,8 @@ Material _barMaterial(WidgetTester tester) {
367367

368368
ShapeDecoration? _indicator(WidgetTester tester) {
369369
return tester
370-
.firstWidget<Ink>(
371-
find.descendant(of: find.byType(FadeTransition), matching: find.byType(Ink)),
370+
.firstWidget<Container>(
371+
find.descendant(of: find.byType(FadeTransition), matching: find.byType(Container)),
372372
)
373373
.decoration
374374
as ShapeDecoration?;

packages/flutter/test/material/navigation_drawer_test.dart

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,14 @@ void main() {
123123
await tester.tap(find.text('AC'));
124124
await tester.pump();
125125

126-
// When no background color is set, only the non-visible indicator Ink is expected.
127-
expect(findDestinationInk('AC'), findsOne);
126+
expect(findDestinationInk('AC'), findsNothing);
128127

129128
// Destination with a custom background color.
130129
await tester.tap(find.byIcon(Icons.access_alarm));
131130
await tester.pump();
132131

133132
// A Material is added with the custom color.
134-
expect(findDestinationInk('Alarm'), findsNWidgets(2));
135-
// The drawer destination Ink is the first one, the second is the indicator's one.
133+
expect(findDestinationInk('Alarm'), findsOne);
136134
final BoxDecoration destinationDecoration =
137135
tester.firstWidget<Ink>(findDestinationInk('Alarm')).decoration! as BoxDecoration;
138136
expect(destinationDecoration.color, color);
@@ -551,8 +549,8 @@ InkWell? _getInkWell(WidgetTester tester) {
551549

552550
ShapeDecoration? _getIndicatorDecoration(WidgetTester tester) {
553551
return tester
554-
.firstWidget<Ink>(
555-
find.descendant(of: find.byType(FadeTransition), matching: find.byType(Ink)),
552+
.firstWidget<Container>(
553+
find.descendant(of: find.byType(FadeTransition), matching: find.byType(Container)),
556554
)
557555
.decoration
558556
as ShapeDecoration?;

packages/flutter/test/material/navigation_drawer_theme_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,8 @@ Material _getMaterial(WidgetTester tester) {
285285

286286
ShapeDecoration? _getIndicatorDecoration(WidgetTester tester) {
287287
return tester
288-
.firstWidget<Ink>(
289-
find.descendant(of: find.byType(FadeTransition), matching: find.byType(Ink)),
288+
.firstWidget<Container>(
289+
find.descendant(of: find.byType(FadeTransition), matching: find.byType(Container)),
290290
)
291291
.decoration
292292
as ShapeDecoration?;

packages/flutter/test/material/navigation_rail_test.dart

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3076,7 +3076,6 @@ void main() {
30763076
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere(
30773077
(RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures',
30783078
);
3079-
30803079
const Rect indicatorRect = Rect.fromLTRB(12.0, 0.0, 68.0, 32.0);
30813080
const Rect includedRect = indicatorRect;
30823081
final Rect excludedRect = includedRect.inflate(10);
@@ -3102,7 +3101,7 @@ void main() {
31023101
)
31033102
..rect(rect: indicatorRect, color: const Color(0x0a6750a4))
31043103
..rrect(
3105-
rrect: RRect.fromLTRBR(12.0, 0.0, 68.0, 32.0, const Radius.circular(16)),
3104+
rrect: RRect.fromLTRBR(12.0, 72.0, 68.0, 104.0, const Radius.circular(16)),
31063105
color: const Color(0xffe8def8),
31073106
),
31083107
);
@@ -3164,7 +3163,7 @@ void main() {
31643163
)
31653164
..rect(rect: indicatorRect, color: const Color(0x0a6750a4))
31663165
..rrect(
3167-
rrect: RRect.fromLTRBR(12.0, 6.0, 68.0, 38.0, const Radius.circular(16)),
3166+
rrect: RRect.fromLTRBR(12.0, 58.0, 68.0, 90.0, const Radius.circular(16)),
31683167
color: const Color(0xffe8def8),
31693168
),
31703169
);
@@ -3230,7 +3229,7 @@ void main() {
32303229
)
32313230
..rect(rect: indicatorRect, color: const Color(0x0a6750a4))
32323231
..rrect(
3233-
rrect: RRect.fromLTRBR(30.0, 24.0, 86.0, 56.0, const Radius.circular(16)),
3232+
rrect: RRect.fromLTRBR(30.0, 96.0, 86.0, 128.0, const Radius.circular(16)),
32343233
color: const Color(0xffe8def8),
32353234
),
32363235
);
@@ -3295,7 +3294,7 @@ void main() {
32953294
)
32963295
..rect(rect: indicatorRect, color: const Color(0x0a6750a4))
32973296
..rrect(
3298-
rrect: RRect.fromLTRBR(0.0, 6.0, 50.0, 38.0, const Radius.circular(16)),
3297+
rrect: RRect.fromLTRBR(0.0, 58.0, 50.0, 90.0, const Radius.circular(16)),
32993298
color: const Color(0xffe8def8),
33003299
),
33013300
);
@@ -3362,7 +3361,7 @@ void main() {
33623361
)
33633362
..rect(rect: indicatorRect, color: const Color(0x0a6750a4))
33643363
..rrect(
3365-
rrect: RRect.fromLTRBR(140.0, 24.0, 196.0, 56.0, const Radius.circular(16)),
3364+
rrect: RRect.fromLTRBR(140.0, 96.0, 196.0, 128.0, const Radius.circular(16)),
33663365
color: const Color(0xffe8def8),
33673366
),
33683367
);
@@ -3402,11 +3401,13 @@ void main() {
34023401
);
34033402

34043403
// Default values from M3 specification.
3405-
const double railMinWidth = 80.0;
34063404
const double indicatorHeight = 32.0;
34073405
const double destinationWidth = 72.0;
34083406
const double destinationHorizontalPadding = 8.0;
34093407
const double indicatorWidth = destinationWidth - 2 * destinationHorizontalPadding; // 56.0
3408+
const double verticalSpacer = 8.0;
3409+
const double verticalIconLabelSpacing = 4.0;
3410+
const double verticalDestinationSpacing = 12.0;
34103411

34113412
// The navigation rail width is larger than default because of the first destination long label.
34123413
final double railWidth = tester.getSize(find.byType(NavigationRail)).width;
@@ -3417,7 +3418,13 @@ void main() {
34173418
final Rect indicatorRect = Rect.fromLTRB(indicatorLeft, 0.0, indicatorRight, indicatorHeight);
34183419
final Rect includedRect = indicatorRect;
34193420
final Rect excludedRect = includedRect.inflate(10);
3420-
const double indicatorHorizontalPadding = (railMinWidth - indicatorWidth) / 2; // 12.0
3421+
3422+
// Compute the vertical position for the selected destination (the one with 'bookmark' icon).
3423+
const double labelHeight = 16; // fontSize is 12 and height is 1.3.
3424+
const double destinationHeight =
3425+
indicatorHeight + verticalIconLabelSpacing + labelHeight + verticalDestinationSpacing;
3426+
const double secondDestinationVerticalOffset = verticalSpacer + destinationHeight;
3427+
const double secondIndicatorVerticalOffset = secondDestinationVerticalOffset;
34213428

34223429
expect(
34233430
inkFeatures,
@@ -3441,10 +3448,10 @@ void main() {
34413448
..rect(rect: indicatorRect, color: const Color(0x0a6750a4))
34423449
..rrect(
34433450
rrect: RRect.fromLTRBR(
3444-
indicatorHorizontalPadding,
3445-
0.0,
3446-
indicatorHorizontalPadding + indicatorWidth,
3447-
indicatorHeight,
3451+
indicatorLeft,
3452+
secondIndicatorVerticalOffset,
3453+
indicatorRight,
3454+
secondIndicatorVerticalOffset + indicatorHeight,
34483455
const Radius.circular(16),
34493456
),
34503457
color: const Color(0xffe8def8),
@@ -3497,6 +3504,9 @@ void main() {
34973504
const double destinationWidth = 72.0;
34983505
const double destinationHorizontalPadding = 8.0;
34993506
const double indicatorWidth = destinationWidth - 2 * destinationHorizontalPadding; // 56.0
3507+
const double verticalSpacer = 8.0;
3508+
const double verticalIconLabelSpacing = 4.0;
3509+
const double verticalDestinationSpacing = 12.0;
35003510

35013511
// The navigation rail width is the default one because labels are short.
35023512
final double railWidth = tester.getSize(find.byType(NavigationRail)).width;
@@ -3516,8 +3526,13 @@ void main() {
35163526
final Rect includedRect = indicatorRect;
35173527
final Rect excludedRect = includedRect.inflate(10);
35183528

3519-
// Icon height is greater than indicator height so the indicator has a vertical offset.
3520-
const double secondIndicatorVerticalOffset = (iconSize - indicatorHeight) / 2;
3529+
// Compute the vertical position for the selected destination (the one with 'bookmark' icon).
3530+
const double labelHeight = 16; // fontSize is 12 and height is 1.3.
3531+
const double destinationHeight =
3532+
iconSize + verticalIconLabelSpacing + labelHeight + verticalDestinationSpacing;
3533+
const double secondDestinationVerticalOffset = verticalSpacer + destinationHeight;
3534+
const double indicatorOffset = (iconSize - indicatorHeight) / 2;
3535+
const double secondIndicatorVerticalOffset = secondDestinationVerticalOffset + indicatorOffset;
35213536

35223537
expect(
35233538
inkFeatures,
@@ -3596,6 +3611,7 @@ void main() {
35963611
const double destinationWidth = 72.0;
35973612
const double destinationHorizontalPadding = 8.0;
35983613
const double indicatorWidth = destinationWidth - 2 * destinationHorizontalPadding; // 56.0
3614+
const double verticalSpacer = 8.0;
35993615
const double verticalDestinationSpacingM3 = 12.0;
36003616

36013617
// The navigation rail width is the default one because labels are short.
@@ -3615,7 +3631,11 @@ void main() {
36153631
final Rect excludedRect = includedRect.inflate(10);
36163632

36173633
// Compute the vertical position for the selected destination (the one with 'bookmark' icon).
3618-
const double secondIndicatorVerticalOffset = verticalDestinationSpacingM3 / 2;
3634+
const double destinationHeight = indicatorHeight + verticalDestinationSpacingM3;
3635+
const double secondDestinationVerticalOffset = verticalSpacer + destinationHeight;
3636+
const double secondIndicatorVerticalOffset =
3637+
secondDestinationVerticalOffset + verticalDestinationSpacingM3 / 2;
3638+
const double secondDestinationHorizontalOffset = 800 - railMinExtendedWidth; // RTL.
36193639

36203640
expect(
36213641
inkFeatures,
@@ -3641,9 +3661,9 @@ void main() {
36413661
// Indicator for the selected destination (the one with 'bookmark' icon).
36423662
..rrect(
36433663
rrect: RRect.fromLTRBR(
3644-
indicatorLeft,
3664+
secondDestinationHorizontalOffset + indicatorLeft,
36453665
secondIndicatorVerticalOffset,
3646-
indicatorRight,
3666+
secondDestinationHorizontalOffset + indicatorRight,
36473667
secondIndicatorVerticalOffset + indicatorHeight,
36483668
const Radius.circular(16),
36493669
),
@@ -6150,8 +6170,8 @@ Widget _buildWidget(Widget child, {bool useMaterial3 = true, bool isRTL = false}
61506170

61516171
ShapeDecoration? _getIndicatorDecoration(WidgetTester tester) {
61526172
return tester
6153-
.firstWidget<Ink>(
6154-
find.descendant(of: find.byType(FadeTransition), matching: find.byType(Ink)),
6173+
.firstWidget<Container>(
6174+
find.descendant(of: find.byType(FadeTransition), matching: find.byType(Container)),
61556175
)
61566176
.decoration
61576177
as ShapeDecoration?;

packages/flutter/test/material/navigation_rail_theme_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ Material _railMaterial(WidgetTester tester) {
327327

328328
ShapeDecoration? _indicatorDecoration(WidgetTester tester) {
329329
return tester
330-
.firstWidget<Ink>(
331-
find.descendant(of: find.byType(NavigationIndicator), matching: find.byType(Ink)),
330+
.firstWidget<Container>(
331+
find.descendant(of: find.byType(NavigationIndicator), matching: find.byType(Container)),
332332
)
333333
.decoration
334334
as ShapeDecoration?;

0 commit comments

Comments
 (0)