Как исправить «прыжки наверх каждого элемента» при прокрутке в Flutter ListView элементов FutureBuilder? - PullRequest
0 голосов
/ 03 мая 2019

Я только начал изучать 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

Проблема может быть очевидной, но я не могу ее понять.

1 Ответ

0 голосов
/ 15 мая 2019

Исправлено!

Хорошо, я получил предложение от «купить dip kek» в группе «Раздражение диско», чтобы поместить точно такой же виджет, ListTile, с фиктивными данными, пока загружается будущее каждого FutureBuilder.Это решило проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...