有没有可能检测抽屉何时打开,以便我们可以运行一些例程来更新其内容?
我的一个典型用例是显示关注者、喜欢者的数量......为此,我需要轮询服务器以获得此信息,然后显示它。
我尝试实现一个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();
}
}
}
这个观察器的初始化
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],
);
}
}
谢谢你的帮助。
9条答案
按热度按时间icomxhvb1#
此答案已过时。请查看@dees91的答案。
抽屉打开/关闭时检测和运行功能
initState()
。dispose()
。状态管理注意事项
如果使用这些函数改变状态以重建抽屉项,可能会遇到以下错误:
Unhandled Exception: setState() or markNeedsBuild() called during build
.这可以通过在initState()source中使用以下两个函数来处理
选项1
选项2
选项1的完整示例
zzzyeukh2#
由于https://github.com/flutter/flutter/pull/67249已与Flutter 2.0合并并发布,因此,以下是检测抽屉打开/关闭的正确方法:
nzkunb0c3#
最佳解决方案
ScaffoldState
有一个有用的方法isDrawerOpen
,它提供打开/关闭的状态。**示例:**在背面按下时,它首先检查抽屉是否打开,如果是,则在退出前首先关闭抽屉。
rur96b6h4#
我认为一个简单的解决方案是覆盖
AppBar
的leading
属性,这样当按下菜单图标时,您就可以访问并基于此运行API调用。然而,我可能误解了你的问题,因为对于你提供的用例,你通常需要以一种可以 * 监听 * 任何更改的方式来管理它,这些更改将自动更新值,所以我不确定当抽屉打开时你试图触发什么。
这里有一个例子。
stszievb5#
您可以简单地使用onDrawerChanged来检测抽屉是在Scaffold小部件中打开还是关闭。
属性:
{void函数(布尔)-绘图更改}
类型:void函数(bool)?
当Scaffold.drawer打开或关闭时调用的可选回调。
范例:
@覆盖小部件构建(BuildContext上下文){
}
5q4ezhmt6#
不幸的是,目前没有readymade solution。
您可以使用肮脏的黑客:观察抽屉的可见位置。
例如,我使用这种方法来同步按钮上图标的动画和抽屉框的位置。
解决此问题的代码如下所示:
如果您只对打开或关闭盒子的最终事件感兴趣,那么调用
initState
和dispose
函数中的回调就足够了。gkl3eglg7#
ScaffoldState中有isDrawerOpen属性,因此您可以在需要检查时进行检查。
创建全局密钥;
将其指定给脚手架
检查应用程序中的任何位置
vpfxa7rd8#
当这个问题被贴出来的时候,要完成这个任务还需要一些技巧。但是在Flutter 2.0中,这就很容易了。在你的Scaffold中,你可以检测到右边的抽屉和左边的抽屉,如下所示。
e0bqpujr9#
您可以使用如下Scaffold.of(context)来检测抽屉状态:
注意:您必须将代码放在生成器小部件中才能使用包含scaffold的上下文。