我刚开始通过一门课程学习 Flutter,其中一个项目是编写一个Hacker News 阅读器应用程序。需要两个 HTTP 请求,一个用于获取 id 的顶部列表,另一个用于使用其 id 的每篇文章。
与 Google 的The Boring Show版本相反,我需要能够在用户向下滚动到热门文章总数(~500)时请求每篇文章。我还想尝试一种比我课程中使用的许多流、转换器和变通方法更简单的方法。
我正在使用 aStreamBuilder
从流中获取顶部 id,通过 abloc
和 a获取文章从中获取FutureBuilder
的每一行 a 。数据要么来自 HTTP 请求,要么来自缓存(一个 sqflite 数据库)。ListView.builder
bloc
它在向下滚动时完美运行,但在向上滚动时,它会跳到除前 4 个项目之外的每个项目的顶部(因为它们已经在那时构建)。
几天来我尝试了不同的结构和模式,每当我FutureBuilder
在ListView.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
问题可能很明显,但我无法弄清楚。