Fix NavigationDrawerDestination backgroundColor obscures interactions (#160239)

## Description

This PR fixes `NavigationDrawerDestination.backgroundColor` obscuring
ink well splashes and overlay.
Before this PR the destination background color was renderer in a
`ColoredBox` which hides the ink well effects. This PR replaces the
`ColorsBox` with an `Ink`.

## Related Issue

Fixes [NavigationDrawerDestination backgroundColor obscures interaction
states](https://github.com/flutter/flutter/issues/160109)

## Tests

Updates 1 test.
This commit is contained in:
Bruno Leroux 2024-12-13 13:06:28 +01:00 committed by GitHub
parent 26ea690af8
commit eaf74bdd11
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 64 additions and 43 deletions

View File

@ -10,6 +10,7 @@ import 'package:flutter/widgets.dart';
import 'color_scheme.dart'; import 'color_scheme.dart';
import 'colors.dart'; import 'colors.dart';
import 'drawer.dart'; import 'drawer.dart';
import 'ink_decoration.dart';
import 'ink_well.dart'; import 'ink_well.dart';
import 'material.dart'; import 'material.dart';
import 'material_localizations.dart'; import 'material_localizations.dart';
@ -196,9 +197,12 @@ class NavigationDrawerDestination extends StatelessWidget {
this.enabled = true, this.enabled = true,
}); });
/// Sets the color of the destination. /// The background color of the destination.
/// ///
/// If this is null, then [NavigationDrawerThemeData.backgroundColor]. /// If this is null, no background is set and [NavigationDrawer.backgroundColor] will be visible.
///
/// This is the background color of the whole rectangular area behind the drawer destination.
/// To customize only the indicator color consider using [NavigationDrawer.indicatorColor].
final Color? backgroundColor; final Color? backgroundColor;
/// The [Widget] (usually an [Icon]) that's displayed for this /// The [Widget] (usually an [Icon]) that's displayed for this
@ -339,9 +343,6 @@ class _NavigationDestinationBuilder extends StatelessWidget {
/// Defaults to true. /// Defaults to true.
final bool enabled; final bool enabled;
/// Sets the color of navigation destination.
///
/// If this is null, then [NavigationDrawerThemeData.backgroundColor] is used.
final Color? backgroundColor; final Color? backgroundColor;
@override @override
@ -386,9 +387,8 @@ class _NavigationDestinationBuilder extends StatelessWidget {
), ),
); );
final Color? color = backgroundColor ?? navigationDrawerTheme.backgroundColor; if (backgroundColor != null) {
if (color != null) { return Ink(color: backgroundColor, child: destination);
return ColoredBox(color: color, child: destination);
} }
return destination; return destination;
} }

View File

@ -82,7 +82,8 @@ void main() {
expect(_getMaterial(tester).color, equals(color)); expect(_getMaterial(tester).color, equals(color));
}); });
testWidgets('NavigationDrawer can update destination background color', testWidgets(
'NavigationDestinationDrawer background color is customizable',
(WidgetTester tester) async { (WidgetTester tester) async {
const Color color = Colors.yellow; const Color color = Colors.yellow;
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
@ -97,7 +98,6 @@ void main() {
NavigationDrawerDestination( NavigationDrawerDestination(
icon: Icon(Icons.ac_unit, color: theme.iconTheme.color), icon: Icon(Icons.ac_unit, color: theme.iconTheme.color),
label: Text('AC', style: theme.textTheme.bodySmall), label: Text('AC', style: theme.textTheme.bodySmall),
backgroundColor: color,
), ),
NavigationDrawerDestination( NavigationDrawerDestination(
icon: Icon(Icons.access_alarm, color: theme.iconTheme.color), icon: Icon(Icons.access_alarm, color: theme.iconTheme.color),
@ -110,17 +110,38 @@ void main() {
), ),
); );
scaffoldKey.currentState!.openDrawer(); Finder findDestinationInk(String label) {
await tester.pump(const Duration(seconds: 1)); // animation done return find.descendant(
final ColoredBox destinationColor = tester.firstWidget<ColoredBox>( of: find.ancestor(
find.descendant( of: find.text(label),
of: find.byType(NavigationDrawerDestination), matching: find.byType(NavigationDrawerDestination),
matching: find.byType(ColoredBox),
), ),
matching: find.byType(Ink),
); );
}
expect(destinationColor.color, equals(color)); scaffoldKey.currentState!.openDrawer();
}); await tester.pump();
await tester.pump(const Duration(seconds: 1)); // Animation done.
// Destination with no custom background color.
await tester.tap(find.text('AC'));
await tester.pump();
expect(findDestinationInk('AC'), findsNothing);
// Destination with a custom background color.
await tester.tap(find.byIcon(Icons.access_alarm));
await tester.pump();
// A Material is added with the custom color.
expect(findDestinationInk('Alarm'), findsOne);
final BoxDecoration destinationDecoration = tester.firstWidget<Ink>(
findDestinationInk('Alarm'),
).decoration! as BoxDecoration;
expect(destinationDecoration.color, color);
},
);
testWidgets('NavigationDrawer can update elevation', testWidgets('NavigationDrawer can update elevation',
(WidgetTester tester) async { (WidgetTester tester) async {