【问题标题】:FutureBuilder makes UI freezeFutureBuilder 使 UI 冻结
【发布时间】:2019-07-24 22:10:54
【问题描述】:

我想使用 FutureBuilder 加载我手机中的歌曲,以显示加载页面。显示所有歌曲的页面包含在 TabBar 中,它是 PageView 的一部分。碰巧,当我从一个页面移动到另一个页面时,FutureBuilder 似乎冻结了 UI,等待操作完成。我无法弄清楚我做错了什么。我在这里报告我的代码和演示冻结的视频。

https://www.youtube.com/watch?v=Hlwj6TKACLc 我放了一个视频,以使问题尽可能清晰。如您所见,CircularProgressIndicator 冻结为每个 UI 组件

class MusicPage extends StatefulWidget {
  @override
  State createState() {
    return _MusicPageState();
  }
}

class _MusicPageState extends State<MusicPage> with 
TickerProviderStateMixin {
  Future<dynamic> _songs;

  @override
  Widget build(BuildContext context) {
    TabController controller = TabController(
      length: 3,
      vsync: this,
    );

return Scaffold(
    appBar: TabBar(
        isScrollable: true,
        controller: controller,
        indicatorColor: Colors.lightBlueAccent,
        tabs: widget.tabs),
    body: TabBarView(controller: controller, children: <Widget>[
      FutureBuilder(
          future: _songs,
          builder: (context, snapshot){
            switch(snapshot.connectionState){
              case ConnectionState.done:
                return Center(child: Text('done'),);

              case ConnectionState.active:
              case ConnectionState.none:
              case ConnectionState.waiting:
                return CircularProgressIndicator();
            }
      }),
      AlbumsGrid(
        albums: AlbumUtils.getCachedAllAlbums(),
      ),
      AuthorsList(
        authors: widget.authors,
      )
    ]));
   }

  @override
   void initState() {
    _songs = MusicFinder.allSongs();
    super.initState();
  }
 }

我希望它不会专注于 Future 加载(就像它是同步的),显然表明它是一个等待指示器。 最后一件事:我省略了一些变量以专注于 FutureBuilder 部分。不要介意他们。

提前感谢大家。

【问题讨论】:

  • 我们需要MusicFinder.allSongs()中的代码
  • MusicFinder 是一个 Flutter 插件,功能在这里:github.com/konaken73/Musicfinder/blob/master/…
  • 您在主线程中执行繁重的操作,请考虑在单独的隔离中执行它们(使用compute 函数)。 Here 就是一个例子。
  • 最后,我选择了另一种方法,使用单例和提供者。无论如何,我必须在更简单的上下文中使用 FutureBuilder(只是一个 StatefulWidget,它在按下按钮时向自身显示一些数据),并且它通过相同的实现完美地工作,如上所述。我想这是 Flutter 调度核心中处理不当的情况。同时,我也认为对我的问题投反对票的人没有正确阅读。

标签: flutter dart freeze


【解决方案1】:

我想说问题不在于FutureBuilder 本身,而在于AlbumUtils.getCachedAllAlbums()。因为您在build 树中调用它,所以在每个绘制的帧上都会调用它,并且在该方法完成之前该帧不会完成加载。我建议尝试将getCachedAllAlbums() 移到build 方法之外。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 2015-01-16
    • 2019-09-16
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    相关资源
    最近更新 更多