Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 颤振:抽屉打开时是否可以检测到?_Flutter - Fatal编程技术网

Flutter 颤振:抽屉打开时是否可以检测到?

Flutter 颤振:抽屉打开时是否可以检测到?,flutter,Flutter,是否可以检测抽屉何时打开,以便我们可以运行一些例程来更新其内容 我的一个典型用例是显示追随者、喜欢者的数量。。。为此,我需要轮询服务器以获取此信息,然后显示它 我尝试实现一个NavigatorObserver来捕捉抽屉被显示/隐藏的时刻,但是NavigatorObserver没有检测到抽屉的任何信息 以下是链接到NavigatorObserver的代码: import 'package:flutter/material.dart'; typedef void OnObservation(Rou

是否可以检测抽屉何时打开,以便我们可以运行一些例程来更新其内容

我的一个典型用例是显示追随者、喜欢者的数量。。。为此,我需要轮询服务器以获取此信息,然后显示它

我尝试实现一个NavigatorObserver来捕捉抽屉被显示/隐藏的时刻,但是NavigatorObserver没有检测到抽屉的任何信息

以下是链接到NavigatorObserver的代码:

import 'package:flutter/material.dart';

typedef void OnObservation(Route<dynamic> route, Route<dynamic> previousRoute);
typedef void OnStartGesture();

class NavigationObserver extends NavigatorObserver {
  OnObservation onPushed;
  OnObservation onPopped;
  OnObservation onRemoved;
  OnObservation onReplaced;
  OnStartGesture onStartGesture;

  @override
  void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
    if (onPushed != null) {
      onPushed(route, previousRoute);
    }
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
    if (onPopped != null) {
      onPopped(route, previousRoute);
    }
  }

  @override
  void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) {
    if (onRemoved != null)
      onRemoved(route, previousRoute);
  }

  @override
  void didReplace({ Route<dynamic> oldRoute, Route<dynamic> newRoute }) {
    if (onReplaced != null)
      onReplaced(newRoute, oldRoute);
  }

  @override
  void didStartUserGesture() { 
    if (onStartGesture != null){
      onStartGesture();
    }
  }
}
导入“包装:颤振/材料.省道”;
类型def void OnObservation(路线路线、前一条路线);
typedef void onStart();
类NavigationObserver扩展了NavigatorObserver{
非观察性;非观察性;
一次观察一次;
未观察未移除;
无观察无替代;
开始姿势开始姿势;
@凌驾
void didPush(路由、路由前一路由){
如果(onpush!=null){
onpush(路由、先前路由);
}
}
@凌驾
void didPop(路由、路由前一路由){
if(onPopped!=null){
onPopped(路线、先前路线);
}
}
@凌驾
void didrove(路由路由,路由前一路由){
if(onRemoved!=null)
onRemoved(路线,以前的路线);
}
@凌驾
void didReplace({Route oldprote,Route newRoute}){
如果(onReplaced!=null)
onReplaced(新路线、旧路线);
}
@凌驾
void didStartUserGesture(){
if(onStart手势!=null){
onStart手势();
}
}
}
以及这个观察器的初始化

void main(){
  runApp(new MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final NavigationObserver _observer = new NavigationObserver()
                                              ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
                                                print('** pushed route: $route');
                                              }
                                              ..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) {
                                                print('** poped route: $route');
                                              }
                                              ..onReplaced = (Route<dynamic> route, Route<dynamic> previousRoute) {
                                                print('** replaced route: $route');
                                              }
                                              ..onStartGesture = () {
                                                print('** on start gesture');
                                              };

  @override
  void initState(){
    super.initState();
  }

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Title',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new SplashScreen(),
        routes: <String, WidgetBuilder> {
          '/splashscreen': (BuildContext context) => new SplashScreen(),
        },
        navigatorObservers: <NavigationObserver>[_observer],
    );
  }
}
void main(){
runApp(新的MyApp());
}
类MyApp扩展了StatefulWidget{
@凌驾
_MyAppState createState()=>new_MyAppState();
}
类MyAppState扩展了状态{
final NavigationObserver_observer=新的NavigationObserver()
..onpush=(路由路由,路由前一个路由){
打印(“**推送路线:$route”);
}
..onPopped=(路由路由,路由前一路由){
打印(“**poped route:$route”);
}
..onReplaced=(路线路线,路线前一条路线){
打印(“**替换路线:$route”);
}
…onStart手势=(){
打印(“**开始手势”);
};
@凌驾
void initState(){
super.initState();
}
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“标题”,
主题:新主题数据(
主样本:颜色。蓝色,
),
主页:新的SplashScreen(),
路线:{
“/splashscreen”:(BuildContext上下文)=>newsplashscreen(),
},
导航观察者:[\u观察者],
);
}
}

谢谢您的帮助。

我认为一个简单的解决方案是覆盖
AppBar
前导
属性,这样您就可以在按下菜单图标时访问,并基于此运行API调用

然而,我可能误解了您的问题,因为对于您提供的用例,您通常需要以一种方式来管理它,您可以听到任何将自动更新值的更改,因此我不确定在抽屉打开时您试图触发什么

无论如何,这里是一个例子

类DrawerExample扩展StatefulWidget{
@凌驾
_DroperExamplestate createState()=>新的_DroperExamplestate();
}
类_DrawerExampleState扩展状态{
GlobalKey _key=new GlobalKey();
int _计数器=0;
_handleDrawer(){
_key.currentState.openDrawer();
设置状态(){
///执行API调用
_计数器++;
});
}
@凌驾
小部件构建(构建上下文){
归还新脚手架(
键:_键,
appBar:新的appBar(
标题:新文本(“抽屉示例”),
标题:对,
前导:新图标按钮(图标:新图标(
图标菜单
),按下按钮:_handleDrawer,),
),
抽屉:新抽屉(
孩子:新中心(
子项:新文本(_counter.toString(),样式:Theme.of(context.textTheme.display1,),
),
),
);
}
}
抽屉打开/关闭时的检测和运行功能
  • 通过任何操作打开抽屉时,运行
    initState()
  • 通过任何操作关闭抽屉时,运行
    dispose()
选项2

SchedulerBinding.instance.addPostFrameCallback((_) {
  // add your code here.
});
选项1的完整示例

WidgetsBinding.instance.addPostFrameCallback((_){
  // Add Your Code here.
});
@override
void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
        // Your Code Here
    });
}

不幸的是,目前没有

你可以使用肮脏的黑客:观察抽屉的可见位置

例如,我使用这种方法来同步按钮上图标的动画和抽屉盒的位置

解决此问题的代码如下所示:

    import 'package:flutter/material.dart';
    import 'package:flutter/scheduler.dart';

    class DrawerListener extends StatefulWidget {
      final Widget child;
      final ValueChanged<FractionalOffset> onPositionChange;

      DrawerListener({
        @required this.child,
        this.onPositionChange,
      });

      @override
      _DrawerListenerState createState() => _DrawerListenerState();
    }

    class _DrawerListenerState extends State<DrawerListener> {
      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,
        );
      }
    }
导入“包装:颤振/材料.省道”;
导入“package:flatter/scheduler.dart”;
类DroperListener扩展StatefulWidget{
最后一个孩子;
最终价值随位置变化而变化;
付款人({
@需要这个孩子,
这是一种改变,
});
@凌驾
_DroperListenerState createState()=>\u DroperListenerState();
}
类_DrawerListenerState扩展状态{
GlobalKey _drawerKey=GlobalKey();
int taskID;
偏置电流偏置;
@凌驾
void initState(){
super.initState();
_后期任务();
}
_后期任务(){
taskID=SchedulerBinding.instance.scheduleFrameCallback((){
@override
void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
        // Your Code Here
    });
}
    import 'package:flutter/material.dart';
    import 'package:flutter/scheduler.dart';

    class DrawerListener extends StatefulWidget {
      final Widget child;
      final ValueChanged<FractionalOffset> onPositionChange;

      DrawerListener({
        @required this.child,
        this.onPositionChange,
      });

      @override
      _DrawerListenerState createState() => _DrawerListenerState();
    }

    class _DrawerListenerState extends State<DrawerListener> {
      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,
        );
      }
    }
/// create a key for the scaffold in order to access it later.
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

@override
Widget build(context) {
   return WillPopScope(
  child: Scaffold(
    // assign key (important)
    key: _scaffoldKey,
    drawer: SideNavigation(),
  onWillPop: () async {
    // drawer is open then first close it
    if (_scaffoldKey.currentState.isDrawerOpen) {
      Navigator.of(context).pop();
      return false;
    }
    // we can now close the app.
    return true;
  });}
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
Scaffold(
      key: scaffoldKey,
      appBar: ..)
bool opened =scaffoldKey.currentState.isDrawerOpen;
Scaffold(
      onDrawerChanged: (isOpened) {
        //todo what you need for left drawer
      },
      onEndDrawerChanged: (isOpened) {
        //todo what you need for right drawer
      },
)
@override
  Widget build(BuildContext context) {
    return Scaffold(
      onDrawerChanged: (isOpened) {
        *//Left drawer, Your code here,*
      },
      onEndDrawerChanged: (isOpened) {
        *//Right drawer, Your code here,*
      },
    );
  }