当Flutter Drawer提取到自定义小部件时会延迟加载

时间:2018-08-28 13:10:00

标签: android dart flutter flutter-layout

我的主页上有一个抽屉,里面充斥着内容和逻辑。例如,我需要获取图像,从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: ...
  );
}

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

有没有一种方法可以设置抽屉中的急切负载以与页面一起初始化?

2 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

在主页中有抽屉的问题:

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

在MyCustomDrawerWidget中具有抽屉的问题

  • 加载时间长,用户体验差

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

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

希望这会有所帮助。