在FutureBuilder项目的Flutter ListView中向上滚动时,如何解决“跳至每个项目的顶部”的问题?

时间:2019-05-03 15:40:54

标签: flutter stream httprequest future flutter-listview

我刚刚开始通过一门课程学习Flutter,其中一个项目是编写 Hacker News阅读器应用程序。需要两个http请求,一个用于获取ID的顶部列表,另一个用于使用其ID的每篇文章。

与Google的 The Boring Show 版本相反,我需要能够在用户向下滚动到热门文章总数(〜500)时要求每篇文章。我还想尝试一种比我的课程中使用的许多流,转换器和解决方法更简单的方法。

我正在使用StreamBuilderbloc的每一行中通过FutureBuilderListView.builder来获取流中的顶级ID。从那个bloc。数据是从http请求或缓存(sqflite数据库)中提取的。

它在向下滚动时效果很好,但是在向上滚动时,它跳到了除前4个项目之外的每个项目的顶部(因为它们已经在该点构建了)。

我已经尝试了数天的不同结构和模式,并且每当我在FutureBuilder中使用ListView.builder时,它的行为总是相同的。 在模拟器和Pixel 3 XL上以调试和发布模式对其进行了尝试。

无聊的表演方法可以将有限数量的文章从StreamBuilder发送到ListView.builder,因为不需要FutureBuilder,但是没有{获取更多文章的方法。

顺便说一句,据我所知,即使每次构建都将ConnectionState设置为waiting,在向上滚动时也不会重新获取项目。

我已在YouTube上添加了有关该问题的视频。希望它能起作用:

YouTube Video of ListView issue while scrolling up

这是显示列表的班级。我组合了小部件以使其紧凑:

class TopList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final StoriesBloc bloc = StoriesProvider.of(context);
    return StreamBuilder<List<int>>(
        stream: bloc.topList,
        builder: (context, snapshot) {
          return snapshot.hasData
              ? ListView.builder(
                  itemBuilder: (context, int index) {
                    return FutureBuilder<ItemModel>(
                        key: Key(snapshot.data[index].toString()),
                        future: bloc.getNewsItem(snapshot.data[index]),
                        builder: (context, snapshot) {
                          switch (snapshot.connectionState) {
                            case ConnectionState.none:
                            case ConnectionState.active:
                            case ConnectionState.waiting:
                              print('${snapshot.connectionState} for $index');
                              return Text('Loading...');
                            case ConnectionState.done:
                              return buildItem(snapshot.data, index);
                          }
                        });
                  },
                )
              : Center(
                  child: CircularProgressIndicator(),
                );
        });
  }

  Widget buildItem(ItemModel item, int index) {
    print('Building row $index');
    return ListTile(
      key: Key(index.toString()),
      leading: CircleAvatar(
        child: Text('${index + 1}', style: TextStyle(fontSize: 14)),
        radius: 16,
      ),
      title: Text(item.title),
      subtitle: Text('${item.score}'),
      trailing: Column(
        children: <Widget>[
          Icon(Icons.comment),
          Text('${item.descendants}'),
        ],
      ),
    );
  }
}

来自Flutter doctor

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel dev, v1.5.8, on Microsoft Windows [Version 10.0.17763.437], locale en-US)

[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[√] Android Studio (version 3.4)
[√] Android Studio (version 3.5)
[√] VS Code (version 1.32.3)
[√] Connected device (1 available)

• No issues found!

我希望上下滚动很流畅,并且会显示“正在加载...”文本以显示正在加载的物品。

这里是向下滚动而不是向上滚动的活动的打印输出:

I/flutter (13405): ConnectionState.waiting for 17
I/flutter (13405): Building row 17
I/flutter (13405): ConnectionState.waiting for 18
I/flutter (13405): Building row 18
I/flutter (13405): ConnectionState.waiting for 19
I/flutter (13405): Building row 19
I/flutter (13405): ConnectionState.waiting for 20
I/flutter (13405): Building row 20
I/flutter (13405): ConnectionState.waiting for 21
I/flutter (13405): Building row 21
I/flutter (13405): ConnectionState.waiting for 22
I/flutter (13405): Building row 22
I/flutter (13405): ConnectionState.waiting for 23
I/flutter (13405): Building row 23
I/flutter (13405): ConnectionState.waiting for 6
I/flutter (13405): Building row 6
I/flutter (13405): ConnectionState.waiting for 5
I/flutter (13405): Building row 5
I/flutter (13405): ConnectionState.waiting for 4
I/flutter (13405): Building row 4
I/flutter (13405): ConnectionState.waiting for 3
I/flutter (13405): Building row 3
I/flutter (13405): ConnectionState.waiting for 2
I/flutter (13405): Building row 2
I/flutter (13405): ConnectionState.waiting for 1
I/flutter (13405): Building row 1
I/flutter (13405): ConnectionState.waiting for 0
I/flutter (13405): Building row 0

问题可能很明显,但我无法弄清楚。在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

解决了!

好吧,在混乱的Discord小组中,“买入求购”提出了一个建议,即在加载每个FutureBuilder的未来时,将完全相同的小部件ListTile和虚拟数据一起放置。解决了这个问题。