我刚刚开始通过一门课程学习Flutter,其中一个项目是编写 Hacker News阅读器应用程序。需要两个http请求,一个用于获取ID的顶部列表,另一个用于使用其ID的每篇文章。
与Google的 The Boring Show 版本相反,我需要能够在用户向下滚动到热门文章总数(〜500)时要求每篇文章。我还想尝试一种比我的课程中使用的许多流,转换器和解决方法更简单的方法。
我正在使用StreamBuilder
从bloc
的每一行中通过FutureBuilder
和ListView.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
问题可能很明显,但我无法弄清楚。在此先感谢您的帮助。
答案 0 :(得分:0)
解决了!
好吧,在混乱的Discord小组中,“买入求购”提出了一个建议,即在加载每个FutureBuilder的未来时,将完全相同的小部件ListTile和虚拟数据一起放置。解决了这个问题。