2

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

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

我正在使用 aStreamBuilder从流中获取顶部 id,通过 abloc和 a获取文章从中获取FutureBuilder的每一行 a 。数据要么来自 HTTP 请求,要么来自缓存(一个 sqflite 数据库)。ListView.builderbloc

它在向下滚动时完美运行,但在向上滚动时,它会跳到除前 4 个项目之外的每个项目的顶部(因为它们已经在那时构建)。

几天来我尝试了不同的结构和模式,每当我FutureBuilderListView.builder. 在模拟器和我的 Pixel 3 XL 上以调试和发布模式进行了尝试。

将有限数量的文章从 a 发送StreamBuilder到a的 Boring ShowListView.builder方法有效,因为 aFutureBuilder不是必需的,但无法获取更多文章。

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

我在 YouTube 上添加了有关该问题的视频。希望它有效:

向上滚动时出现 ListView 问题的 YouTube 视频

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

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

问题可能很明显,但我无法弄清楚。

4

1 回答 1

2

解决它!

好吧,从颤振 Discord 组的“buy dip kek”那里得到了一个建议,即在每个 FutureBuilder 的未来加载时放置完全相同的小部件 ListTile 和虚拟数据。这解决了这个问题。

于 2019-05-14T21:55:13.387 回答