Flutter: possible to detect when a drawer is open?

后端 未结 4 1711
Happy的楠姐
Happy的楠姐 2021-01-04 13:53

Is it possible to detect when a Drawer is open so that we can run some routine to update its content?

A typical use case I have would be to display the number of fol

4条回答
  •  无人及你
    2021-01-04 14:46

    Unfortunately, at the moment there is no readymade solution.

    You can use the dirty hack for this: to observe the visible position of the Drawer.

    For example, I used this approach to synchronise the animation of the icon on the button and the location of the Drawer box.

    The code that solves this problem you can see below:

        import 'package:flutter/material.dart';
        import 'package:flutter/scheduler.dart';
    
        class DrawerListener extends StatefulWidget {
          final Widget child;
          final ValueChanged onPositionChange;
    
          DrawerListener({
            @required this.child,
            this.onPositionChange,
          });
    
          @override
          _DrawerListenerState createState() => _DrawerListenerState();
        }
    
        class _DrawerListenerState extends State {
          GlobalKey _drawerKey = GlobalKey();
          int taskID;
          Offset currentOffset;
    
          @override
          void initState() {
            super.initState();
            _postTask();
          }
    
          _postTask() {
            taskID = SchedulerBinding.instance.scheduleFrameCallback((_) {
              if (widget.onPositionChange != null) {
                final RenderBox box = _drawerKey.currentContext?.findRenderObject();
                if (box != null) {
                  Offset newOffset = box.globalToLocal(Offset.zero);
                  if (newOffset != currentOffset) {
                    currentOffset = newOffset;
                    widget.onPositionChange(
                      FractionalOffset.fromOffsetAndRect(
                        currentOffset,
                        Rect.fromLTRB(0, 0, box.size.width, box.size.height),
                      ),
                    );
                  }
                }
              }
    
              _postTask();
            });
          }
    
          @override
          void dispose() {
            SchedulerBinding.instance.cancelFrameCallbackWithId(taskID);
            if (widget.onPositionChange != null) {
              widget.onPositionChange(FractionalOffset(1.0, 0));
            }
            super.dispose();
          }
    
          @override
          Widget build(BuildContext context) {
            return Container(
              key: _drawerKey,
              child: widget.child,
            );
          }
        }
    

    If you are only interested in the final events of opening or closing the box, it is enough to call the callbacks in initState and dispose functions.

提交回复
热议问题