Я только начал изучать Flutter через курс, и один из проектов - написать приложение Hacker News reader . Требуются два HTTP-запроса: один для получения верхнего списка идентификаторов и один для каждой статьи с использованием ее идентификатора.
Вопреки версии Google Boring Show , мне нужно иметь возможность запрашивать каждую статью, когда пользователь прокручивает список до общего количества популярных статей (~ 500). Я также хотел попробовать более простой способ, чем многие потоки, преобразователи и обходные пути, которые использовались в моем курсе.
Я использую StreamBuilder
, чтобы получить верхние идентификаторы из потока через bloc
и FutureBuilder
для каждой строки ListView.builder
, где статья извлекается из этого bloc
. Данные извлекаются из HTTP-запроса или из кэша (база данных sqflite).
Он отлично работает при прокрутке вниз, но при прокрутке вверх переходит на верх каждого элемента, за исключением первых 4 элементов (потому что они уже построены в этот момент).
Я пробовал разные структуры и шаблоны в течение нескольких дней, и они всегда ведут себя одинаково, когда я использую FutureBuilder
внутри ListView.builder
.
Пробовал в эмуляторе и на моем Pixel 3 XL в режиме отладки и выпуска.
Метод скучного показа для отправки ограниченного числа статей от StreamBuilder
до ListView.builder
работает, потому что FutureBuilder
не требуется, но нет способа получить больше статей.
Кстати, из того, что я могу сказать, элементы НЕ выбираются при прокрутке вверх, даже если для ConnectionState
установлено значение waiting
для каждой сборки.
Я добавил видео этой проблемы на YouTube. Надеюсь, что это работает:
YouTube видео о ListView проблема при прокрутке вверх
Вот класс, в котором отображается список. Я соединил виджеты, чтобы сделать его компактным:
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
Проблема может быть очевидной, но я не могу ее понять.