我的主页上有一个抽屉,里面充斥着内容和逻辑。例如,我需要获取图像,从Internet获取一些数据等等。在扩展了MyCustomDrawerWidget
的新StatefulWidget
中提取Drawer之后,其状态具有build
功能,如下所示:
@override
Widget build(BuildContext context) {
return Drawer(
child: ...
);
}
我的HomePageState
具有build
功能,如下所示:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home page'),
),
drawer: MyCustomDrawerWidget(),
body: ...
);
}
在重构了这样的代码之后,我注意到页面加载时抽屉没有初始化。它会在我打开抽屉后立即初始化,这很糟糕,因为用户需要等待数据加载。
有没有一种方法可以设置抽屉中的急切负载以与页面一起初始化?
答案 0 :(得分:1)
我有同样的问题。 Scaffold
仅在必要时附加抽屉。
解决方案:将数据加载逻辑移到父窗口小部件中。您仍然可以将其封装在单独的模型类中(例如DrawerModel
),但是在初始化父窗口小部件时必须实例化该类。将其保留在父级的State
中。将DrawerModel
传递到您的抽屉小部件。
在使用流和期货时,您必须要小心一点,因为通常无法重新订阅。我建议您在与StreamBuilder
中的BehaviorSubject
连接的抽屉式小部件中使用DrawerModel
。
这就是BLoC模式。您需要一个代码示例吗?
答案 1 :(得分:1)
在主页中有抽屉的问题:
在MyCustomDrawerWidget中具有抽屉的问题:
我会建议使用hybrid
方法来解决问题。
future
到MyCustomDrawerWidget
(如果用户在网络通话完成之前打开抽屉,我们可以根据将来的值显示加载程序)将与抽屉相关的逻辑和内容移动到MyCustomDrawerWidget中。
class MyCustomDrawerWidget extends StatelessWidget {
var _future;
MyCustomDrawerWidget(this._future);
@override
Widget build(BuildContext context) {
return new Drawer(
child: FutureBuilder(
builder: (context, snapshot) {
if (snapshot.hasData) {
var data = snapshot.data;
return new Text(data);
} else {
return new Text("loading");
}
},
future: _future,
),
);
}
}
在主页
中@override
Widget build(BuildContext context) {
val future = Future.delayed(Duration(seconds: 10), () => "new value") //network call
return Scaffold(
appBar: AppBar(
title: Text('Home page'),
),
drawer: MyCustomDrawerWidget(future),
body: ...
);
}
希望这会有所帮助。