Android 提取到自定义小部件时抖动抽屉延迟加载

Android 提取到自定义小部件时抖动抽屉延迟加载,android,dart,flutter,flutter-layout,Android,Dart,Flutter,Flutter Layout,我的主页上有一个抽屉,里面堆满了内容和逻辑。例如,我需要获取一幅图像,从互联网上获取一些数据等等。在新的MyCustomDrawerWidget中提取抽屉后,它扩展了StatefulWidget,其状态具有build功能,如下所示: @override Widget build(BuildContext context) { return Drawer( child: ... ); } @override Widget build(BuildContext context) {

我的主页上有一个抽屉,里面堆满了内容和逻辑。例如,我需要获取一幅图像,从互联网上获取一些数据等等。在新的
MyCustomDrawerWidget
中提取抽屉后,它扩展了
StatefulWidget
,其状态具有
build
功能,如下所示:

@override
Widget build(BuildContext context) {
  return Drawer(
    child: ...
  );
}
@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Home page'),
    ),
    drawer: MyCustomDrawerWidget(),
    body: ...
  );
}
我的
HomePageState
具有
build
功能,如下所示:

@override
Widget build(BuildContext context) {
  return Drawer(
    child: ...
  );
}
@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Home page'),
    ),
    drawer: MyCustomDrawerWidget(),
    body: ...
  );
}
在像这样重构代码之后,我注意到当页面加载时抽屉并没有被初始化。它将在我打开抽屉后初始化,这是不好的,因为用户需要等待数据加载


有没有一种方法可以设置抽屉上的急加载,以便与页面一起初始化?

我也遇到了同样的问题。
Scaffold
仅在必要时连接抽屉

解决方案:将数据加载逻辑移动到父窗口小部件中。您仍然可以将其封装在单独的模型类中(例如,
DrawerModel
),但必须在初始化父小部件时实例化此类。将其保持在父级的
状态
。将
DrawerModel
传递给抽屉小部件

在使用streams和futures时,您必须小心一点,因为它们通常无法重新订阅。我建议您在抽屉小部件中使用
StreamBuilder
,该抽屉小部件连接到
BehaviorSubject
中的
DrawerModel


这就是集团模式。您需要一个代码示例吗?

主页上有抽屉的问题

  • 内容、更多逻辑、获取图像、从互联网获取数据等等

MyCustomDrawerWidget中有抽屉的问题

  • 加载时间,糟糕的用户体验
我建议采用
混合
方法来解决这个问题

  • 在主页中触发网络调用
  • 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: ...
  );
}
希望这有帮助