-
Notifications
You must be signed in to change notification settings - Fork 30.2k
Description
I am developing a gaming app. The “App Bar” has a pause icon and a hamburger icon.
- Clicking on “pause” icon will pause the timer & displays a dialog to resume the game.
- Clicking on the “hamburger” icon pauses the timer and opens the drawer.
- Clicking on any actions within the drawer will take you back to the game screen with a dialog to resume the game.
- Exiting the drawer without clicking on any actions (ListTile items) should also display the dialog to resume the game.
WHAT’S IN THE CURRENT API:
In the current API, there’s a DrawerController class, that can be used to provide extra behavior to your drawer.
There’s a “drawerCallback” property in this class that lets you set the method that needs to be called when the drawer is opened or closed. The boolean value is “true” when drawer is open, “false” when the drawer is closed.
DrawerController drawerController = DrawerController(
child: _drawer,
alignment: DrawerAlignment.start,
drawerCallback: (bool open) => _onDrawerClose(open),
);
But there’s a new instance of DrawerController created in the Scaffold class and we cannot set the above such created DrawerController to Scaffold in both _buildDrawer and _buildEndDrawer methods.
void _buildDrawer(List<LayoutId> children, TextDirection textDirection) {
if (widget.drawer != null) {
assert(hasDrawer);
_addIfNonNull(
children,
DrawerController(
key: _drawerKey,
alignment: DrawerAlignment.start,
child: widget.drawer,
drawerCallback: _drawerOpenedCallback,
dragStartBehavior: widget.drawerDragStartBehavior,
scrimColor: widget.drawerScrimColor,
edgeDragWidth: widget.drawerEdgeDragWidth,
),
Thus, the DrawerController instance that you have created is completely orphaned and there’s no way to detect when the drawer is closed.
MISSING LINK:
There’s a missing link between Drawer, DrawerController and Scaffold classes. Though there is api code to set a call back method, the same is not tied back to scaffold.
PROPOSED SOLUTION:
I made the below changes in my code base and it works as desired.
-
Provide “DrawerCallback” as an optional attribute/property in scaffold.dart class.
final DrawerCallback drawerCallback; -
Modify scaffold. _buildDrawer (I am not looking into _buildEndDrawer) method to use the input “drawerCallback” value.
void _buildDrawer(List<LayoutId> children, TextDirection textDirection) {
if (widget.drawer != null) {
assert(hasDrawer);
_addIfNonNull(
children,
DrawerController(
key: _drawerKey,
alignment: DrawerAlignment.start,
child: widget.drawer,
drawerCallback: widget.drawerCallback,
dragStartBehavior: widget.drawerDragStartBehavior,
scrimColor: widget.drawerScrimColor,
edgeDragWidth: widget.drawerEdgeDragWidth,
), -
Specify the call back method when creating the Scaffold.
Scaffold _scaffold = Scaffold(
drawerScrimColor: Colors.red, //Theme.of(context).backgroundColor,
appBar: _appBar(context, state),
drawer: _drawer(),
drawerCallback: (bool open) => _onDrawerClose(open, context),
body: _body(state, context),
bottomNavigationBar: _bottomNav(state, context),
); -
By doing the above, whenever my drawer closes I am able to display the dialog screen that shows the resume button to resume the game.
_onDrawerClose(bool isDrawerOpen, BuildContext context) {
// when the drawer closes, do this
if (!isDrawerOpen) {
PauseTimerScreen().displayDialog(context);
}
}
ALTERNATE PROPOSED SOLUTION:
I am not sure of the reason, but the below solution didn’t work, ideally should have.
-
Provide “DrawerController” as an optional attribute/property in scaffold.dart class.
final DrawerController drawerController; -
Let the user set custom value when needed as below,
Scaffold _scaffold = Scaffold(
drawerScrimColor: Colors.red, //Theme.of(context).backgroundColor,
appBar: _appBar(context, state),
drawer: _drawer(),
drawerController: , -
Modify Scaffold. _buildDrawer method to use the DrawerController instance if provided else create new as earlier.
-
In this case, whenever I had drawerController property defined, my drawer was not opening at all. When I don’t have this property specified, the drawer used to open but of course, the callback was not being captured.
This is an important feature, there were requests before too. [https://github.com//pull/20856]
[https://github.com//issues/20581]
Looks like the callback approach was decided as not the best, but please let me know if this is being implemented.
Thank you,
Arathi