是否可以检测到抽屉何时打开,以便我们可以运行一些例程来更新其内容?
我的典型用例是显示关注者,喜欢者的数量……为此,我需要轮询服务器以获取此信息,然后进行显示。
我尝试实现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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
和这个观察者的初始化
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],
);
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助。
Viv*_*sal 15
最佳解决方案
ScaffoldState有一个有用的方法isDrawerOpen可以提供打开/关闭的状态。
示例:在背面按下时,它首先检查抽屉是否打开,如果是,则首先将在退出前关闭。
/// 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;
});}
Run Code Online (Sandbox Code Playgroud)
pep*_*pen 12
这对我有用。
通过任何操作打开抽屉时运行initState。
当关闭抽屉时,请执行任何操作处置。
希望对您有所帮助。
class MyDrawer extends StatefulWidget {
@override
_MyDrawerState createState() => _MyDrawerState();
}
class _MyDrawerState extends State<MyDrawer> {
@override
void initState() {
super.initState();
print("open");
}
@override
void dispose() {
print("close");
super.dispose();
}
@override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: <Widget>[
Text("test1"),
Text("test2"),
Text("test3"),
],
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以简单地使用onDrawerChanged来检测 Scaffold 小部件中抽屉是否打开或关闭。
财产 :
{无效函数(布尔)?onDrawerChanged}
类型:void Function(bool)?
打开或关闭 Scaffold.drawer 时调用的可选回调。
例子 :
@override Widget build(BuildContext context) {
return Scaffold(
onDrawerChanged:(val){
if(val){
setState(() {
//foo bar;
});
}else{
setState(() {
//foo bar;
});
}
},
drawer: Drawer(
child: Container(
)
));
Run Code Online (Sandbox Code Playgroud)
}
由于https://github.com/flutter/flutter/pull/67249已经与 Flutter 2.0 合并并发布,这里是检测抽屉打开/关闭的正确方法:
Scaffold(
onDrawerChanged: (isOpened) {
//todo what you need for left drawer
},
onEndDrawerChanged: (isOpened) {
//todo what you need for right drawer
},
)
Run Code Online (Sandbox Code Playgroud)
我认为一个简单的解决方案是覆盖leading您的属性,AppBar以便您可以在按下菜单图标时访问并基于此运行API调用。
但是我可能会误解您的问题,因为对于您提供的用例,通常需要以一种可以监听任何会自动更新值的更改的方式来管理它,所以我不确定您尝试在什么情况下触发什么抽屉是打开的。
无论如何,这是示例。
class DrawerExample extends StatefulWidget {
@override
_DrawerExampleState createState() => new _DrawerExampleState();
}
class _DrawerExampleState extends State<DrawerExample> {
GlobalKey<ScaffoldState> _key = new GlobalKey<ScaffoldState>();
int _counter =0;
_handleDrawer(){
_key.currentState.openDrawer();
setState(() {
///DO MY API CALLS
_counter++;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _key,
appBar: new AppBar(
title: new Text("Drawer Example"),
centerTitle: true,
leading: new IconButton(icon: new Icon(
Icons.menu
),onPressed:_handleDrawer,),
),
drawer: new Drawer(
child: new Center(
child: new Text(_counter.toString(),style: Theme.of(context).textTheme.display1,),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3719 次 |
| 最近记录: |