【问题标题】:Flutter Drawer lazy load when extracted to custom widget提取到自定义小部件时 Flutter Drawer 延迟加载
【发布时间】:2018-08-28 13:09:59
【问题描述】:

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

@override
Widget build(BuildContext context) {
  return Drawer(
    child: ...
  );
}

我的HomePageStatebuild 函数,看起来像这样:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Home page'),
    ),
    drawer: MyCustomDrawerWidget(),
    body: ...
  );
}

像这样重构代码后,我注意到页面加载时抽屉没有被初始化。它会在我打开抽屉后初始化,这很糟糕,因为用户需要等待数据加载。

有没有办法在抽屉上设置预先加载以与页面一起初始化?

【问题讨论】:

    标签: android dart flutter flutter-layout


    【解决方案1】:

    我遇到了同样的问题。 Scaffold 仅在必要时附加抽屉。

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

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

    这就是 BLoC 模式。需要代码示例吗?

    【讨论】:

      【解决方案2】:

      主页面中的抽屉存在问题:

      • 内容、更多逻辑、获取图像、从 Internet 获取一些数据等等。

      MyCustomDrawerWidget 中的抽屉存在问题

      • 加载时间,糟糕的用户体验

      我会建议使用hybrid 方法来解决问题。

      • MainPage中触发网络调用
      • 发送futureMyCustomDrawerWidget(如果用户在网络调用完成之前打开抽屉,我们可以根据未来值显示加载器)
      • 将drawer相关的逻辑和内容移到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: ...
        );
      }
      

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-11
        • 1970-01-01
        • 2021-03-10
        • 2015-03-27
        • 2018-05-29
        • 2018-09-05
        • 1970-01-01
        相关资源
        最近更新 更多