Fix NavigationRail's indicator inkwell doesn't support transparent color. (#136359)
fixes [NavigationRail can't have a transparent Hover color because there is always opacity set](https://github.com/flutter/flutter/issues/135866) ### Code sample <details> <summary>expand to view the code sample</summary> ```dart import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.green).copyWith( primary: Colors.transparent, ), ), home: const Example(), ); } } class Example extends StatefulWidget { const Example({Key? key}) : super(key: key); @override State<StatefulWidget> createState() => _ExampleState(); } class _ExampleState extends State<Example> { int _selectedIndex = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('NavigationRail Example'), ), body: Row( children: <Widget>[ NavigationRail( selectedIndex: _selectedIndex, onDestinationSelected: (int index) { setState(() { _selectedIndex = index; }); }, labelType: NavigationRailLabelType.all, destinations: const <NavigationRailDestination>[ NavigationRailDestination( icon: Icon(Icons.favorite_border), selectedIcon: Icon(Icons.favorite), label: Text('First'), ), NavigationRailDestination( icon: Icon(Icons.bookmark_border), selectedIcon: Icon(Icons.book), label: Text('Second'), ), NavigationRailDestination( icon: Icon(Icons.star_border), selectedIcon: Icon(Icons.star), label: Text('Third'), ), ], ), const VerticalDivider(thickness: 1, width: 1), Expanded( child: Center( child: Text('Selected Index: $_selectedIndex'), ), ) ], ), ); } } ``` </details>
This commit is contained in:
@@ -782,6 +782,13 @@ class _RailDestination extends StatelessWidget {
|
||||
}
|
||||
|
||||
final ColorScheme colors = Theme.of(context).colorScheme;
|
||||
final bool primaryColorAlphaModified = colors.primary.alpha < 255.0;
|
||||
final Color effectiveSplashColor = primaryColorAlphaModified
|
||||
? colors.primary
|
||||
: colors.primary.withOpacity(0.12);
|
||||
final Color effectiveHoverColor = primaryColorAlphaModified
|
||||
? colors.primary
|
||||
: colors.primary.withOpacity(0.04);
|
||||
return Semantics(
|
||||
container: true,
|
||||
selected: selected,
|
||||
@@ -793,8 +800,8 @@ class _RailDestination extends StatelessWidget {
|
||||
onTap: disabled ? null : onTap,
|
||||
borderRadius: BorderRadius.all(Radius.circular(minWidth / 2.0)),
|
||||
customBorder: indicatorShape,
|
||||
splashColor: colors.primary.withOpacity(0.12),
|
||||
hoverColor: colors.primary.withOpacity(0.04),
|
||||
splashColor: effectiveSplashColor,
|
||||
hoverColor: effectiveHoverColor,
|
||||
useMaterial3: material3,
|
||||
indicatorOffset: indicatorOffset,
|
||||
applyXOffset: applyXOffset,
|
||||
|
||||
@@ -3548,6 +3548,63 @@ void main() {
|
||||
expect(bcdLabelOpacity, closeTo(0.38, 0.01));
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('NavigationRail indicator inkwell can be transparent', (WidgetTester tester) async {
|
||||
// This is a regression test for https://github.com/flutter/flutter/issues/135866.
|
||||
final ThemeData theme = ThemeData(
|
||||
colorScheme: const ColorScheme.light().copyWith(primary: Colors.transparent),
|
||||
// Material 3 defaults to InkSparkle which is not testable using paints.
|
||||
splashFactory: InkSplash.splashFactory,
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Row(
|
||||
children: <Widget>[
|
||||
NavigationRail(
|
||||
selectedIndex: 1,
|
||||
destinations: const <NavigationRailDestination>[
|
||||
NavigationRailDestination(
|
||||
icon: Icon(Icons.favorite_border),
|
||||
selectedIcon: Icon(Icons.favorite),
|
||||
label: Text('ABC'),
|
||||
),
|
||||
NavigationRailDestination(
|
||||
icon: Icon(Icons.bookmark_border),
|
||||
selectedIcon: Icon(Icons.bookmark),
|
||||
label: Text('DEF'),
|
||||
),
|
||||
],
|
||||
labelType: NavigationRailLabelType.all,
|
||||
),
|
||||
const Expanded(
|
||||
child: Text('body'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
));
|
||||
|
||||
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
||||
await gesture.addPointer();
|
||||
await gesture.moveTo(tester.getCenter(find.byIcon(Icons.favorite_border)));
|
||||
await tester.pumpAndSettle();
|
||||
RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||
|
||||
expect(inkFeatures, paints..rect(color: Colors.transparent));
|
||||
|
||||
await gesture.down(tester.getCenter(find.byIcon(Icons.favorite_border)));
|
||||
await tester.pump(); // Start the splash and highlight animations.
|
||||
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
|
||||
|
||||
inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||
expect(inkFeatures, paints..circle(color: Colors.transparent));
|
||||
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933
|
||||
|
||||
group('Material 2', () {
|
||||
// These tests are only relevant for Material 2. Once Material 2
|
||||
// support is deprecated and the APIs are removed, these tests
|
||||
|
||||
Reference in New Issue
Block a user