From b7fbe68d4ec2105eb7b8e3a68ce3dfbabc5a72a6 Mon Sep 17 00:00:00 2001 From: Aliasgar Vohra <38110731+aliasgar4558@users.noreply.github.com> Date: Thu, 21 Mar 2024 22:18:23 +0530 Subject: [PATCH] =?UTF-8?q?[adaptive=5Fscaffold]=20:=20=F0=9F=90=9B=20#141?= =?UTF-8?q?938=20-=20Drawer=20stays=20open=20even=20on=20destination=20tap?= =?UTF-8?q?.=20(#6289)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (#141938) *Changes included in PR are listed as follows* - As per material guidelines, Drawer shall be dismissed when user taps any destination/item. If drawer is open, and user taps on any item, before calling onDestinationSelected() - we are now dismissing drawer. - CHANGELOG.md file updated. - Updated to v0.1.9. *Issue : https://github.com/flutter/flutter/issues/141938* --- packages/flutter_adaptive_scaffold/AUTHORS | 3 +- .../flutter_adaptive_scaffold/CHANGELOG.md | 5 +- .../lib/src/adaptive_scaffold.dart | 20 +++- .../flutter_adaptive_scaffold/pubspec.yaml | 2 +- .../test/adaptive_scaffold_test.dart | 113 ++++++++++++++++++ 5 files changed, 138 insertions(+), 5 deletions(-) diff --git a/packages/flutter_adaptive_scaffold/AUTHORS b/packages/flutter_adaptive_scaffold/AUTHORS index 0bbdf210f3c2..f53e3e1620fb 100644 --- a/packages/flutter_adaptive_scaffold/AUTHORS +++ b/packages/flutter_adaptive_scaffold/AUTHORS @@ -4,4 +4,5 @@ # Name/Organization Google Inc. -Jason C.H \ No newline at end of file +Jason C.H +Aliasgar Vohra \ No newline at end of file diff --git a/packages/flutter_adaptive_scaffold/CHANGELOG.md b/packages/flutter_adaptive_scaffold/CHANGELOG.md index 623da45aaf86..8873f7e26452 100644 --- a/packages/flutter_adaptive_scaffold/CHANGELOG.md +++ b/packages/flutter_adaptive_scaffold/CHANGELOG.md @@ -1,10 +1,11 @@ -## NEXT +## 0.1.9 +* FIX : Drawer stays open even on destination tap - [flutter/flutter#141938](https://github.com/flutter/flutter/issues/141938) * Updates minimum supported SDK version to Flutter 3.13/Dart 3.1. ## 0.1.8 -* Adds `transitionDuration` parameter for specifying how long the animation should be. +* Adds `transitionDuration` parameter for specifying how long the animation should be. ## 0.1.7+2 diff --git a/packages/flutter_adaptive_scaffold/lib/src/adaptive_scaffold.dart b/packages/flutter_adaptive_scaffold/lib/src/adaptive_scaffold.dart index d134f73cb79f..531a088b7943 100644 --- a/packages/flutter_adaptive_scaffold/lib/src/adaptive_scaffold.dart +++ b/packages/flutter_adaptive_scaffold/lib/src/adaptive_scaffold.dart @@ -502,12 +502,16 @@ class AdaptiveScaffold extends StatefulWidget { } class _AdaptiveScaffoldState extends State { + // Global scaffold key that will help to manage drawer state. + final GlobalKey _scaffoldKey = GlobalKey(); + @override Widget build(BuildContext context) { final NavigationRailThemeData navRailTheme = Theme.of(context).navigationRailTheme; return Scaffold( + key: _scaffoldKey, appBar: widget.drawerBreakpoint.isActive(context) && widget.useDrawer || (widget.appBarBreakpoint?.isActive(context) ?? false) ? widget.appBar ?? AppBar() @@ -523,7 +527,7 @@ class _AdaptiveScaffoldState extends State { .map((NavigationDestination destination) => AdaptiveScaffold.toRailDestination(destination)) .toList(), - onDestinationSelected: widget.onSelectedIndexChange, + onDestinationSelected: _onDrawerDestinationSelected, ), ) : null, @@ -670,6 +674,20 @@ class _AdaptiveScaffoldState extends State { ), ); } + + void _onDrawerDestinationSelected(int index) { + if (widget.useDrawer) { + // If [useDrawer] is true, then retrieve the current state. + final ScaffoldState? scaffoldCurrentContext = _scaffoldKey.currentState; + if (scaffoldCurrentContext != null) { + if (scaffoldCurrentContext.isDrawerOpen) { + // If drawer is open, call [closeDrawer] to dismiss drawer as per material guidelines. + scaffoldCurrentContext.closeDrawer(); + } + } + } + widget.onSelectedIndexChange?.call(index); + } } class _BrickLayout extends StatelessWidget { diff --git a/packages/flutter_adaptive_scaffold/pubspec.yaml b/packages/flutter_adaptive_scaffold/pubspec.yaml index 6ebf6d894f92..a494b4fc6111 100644 --- a/packages/flutter_adaptive_scaffold/pubspec.yaml +++ b/packages/flutter_adaptive_scaffold/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_adaptive_scaffold description: Widgets to easily build adaptive layouts, including navigation elements. -version: 0.1.8 +version: 0.1.9 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_adaptive_scaffold%22 repository: https://github.com/flutter/packages/tree/main/packages/flutter_adaptive_scaffold diff --git a/packages/flutter_adaptive_scaffold/test/adaptive_scaffold_test.dart b/packages/flutter_adaptive_scaffold/test/adaptive_scaffold_test.dart index 3761fbfe29a0..808b03ea1389 100644 --- a/packages/flutter_adaptive_scaffold/test/adaptive_scaffold_test.dart +++ b/packages/flutter_adaptive_scaffold/test/adaptive_scaffold_test.dart @@ -501,6 +501,119 @@ void main() { }, ); + testWidgets( + 'when drawer item tap, it shall close the already open drawer', + (WidgetTester tester) async { + //region Keys + const ValueKey firstDestinationIconKey = ValueKey( + 'first-normal-icon', + ); + const ValueKey firstDestinationSelectedIconKey = ValueKey( + 'first-selected-icon', + ); + const ValueKey lastDestinationIconKey = ValueKey( + 'last-normal-icon', + ); + const ValueKey lastDestinationSelectedIconKey = ValueKey( + 'last-selected-icon', + ); + //endregion + + //region Finder for destinations as per its icon. + final Finder lastDestinationWithIcon = find.byKey( + lastDestinationIconKey, + ); + final Finder lastDestinationWithSelectedIcon = find.byKey( + lastDestinationSelectedIconKey, + ); + //endregion + + const List destinations = [ + NavigationDestination( + icon: Icon( + Icons.inbox_outlined, + key: firstDestinationIconKey, + ), + selectedIcon: Icon( + Icons.inbox, + key: firstDestinationSelectedIconKey, + ), + label: 'Inbox', + ), + NavigationDestination( + icon: Icon( + Icons.video_call_outlined, + key: lastDestinationIconKey, + ), + selectedIcon: Icon( + Icons.video_call, + key: lastDestinationSelectedIconKey, + ), + label: 'Video', + ), + ]; + int selectedDestination = 0; + + await tester.pumpWidget( + MaterialApp( + home: MediaQuery( + data: const MediaQueryData(size: Size(450, 900)), + child: StatefulBuilder( + builder: ( + BuildContext context, + void Function(void Function()) setState, + ) { + return AdaptiveScaffold( + destinations: destinations, + selectedIndex: selectedDestination, + smallBreakpoint: TestBreakpoint400(), + drawerBreakpoint: TestBreakpoint400(), + onSelectedIndexChange: (int value) { + setState(() { + selectedDestination = value; + }); + }, + ); + }, + ), + ), + ), + ); + + expect(selectedDestination, 0); + Finder fDrawer = find.byType(Drawer); + Finder fNavigationRail = find.descendant( + of: fDrawer, + matching: find.byType(NavigationRail), + ); + expect(fDrawer, findsNothing); + expect(fNavigationRail, findsNothing); + + final ScaffoldState state = tester.state(find.byType(Scaffold)); + state.openDrawer(); + await tester.pumpAndSettle(Durations.short4); + expect(state.isDrawerOpen, isTrue); + + // Need to find again as Scaffold's state has been updated + fDrawer = find.byType(Drawer); + fNavigationRail = find.descendant( + of: fDrawer, + matching: find.byType(NavigationRail), + ); + expect(fDrawer, findsOneWidget); + expect(fNavigationRail, findsOneWidget); + + expect(lastDestinationWithIcon, findsOneWidget); + expect(lastDestinationWithSelectedIcon, findsNothing); + + await tester.ensureVisible(lastDestinationWithIcon); + await tester.tap(lastDestinationWithIcon); + await tester.pumpAndSettle(Durations.short4); + expect(selectedDestination, 1); + expect(state.isDrawerOpen, isFalse); + }, + ); + // This test checks whether AdaptiveScaffold.standardNavigationRail function // creates a NavigationRail widget as expected with groupAlignment provided, // and checks whether the NavigationRail's groupAlignment matches the expected value.