Индекс Listview всегда сбрасывается

У меня есть виджет, который возвращает ListView. Когда элемент в ListView выбран, я показываю CircularProgressIndicator на экране во время загрузки данных для этого элемента, а после завершения загрузки я снова показываю ListView. Однако после завершения загрузки и закрытия CircularProgressIndicator индекс ListView всегда сбрасывается (то есть индекс становится равным 0). Другими словами, без использования управления состоянием я не могу отслеживать положение пользователя в списке перед загрузкой. Как мне это сделать?

Пример кода приведен ниже:

class ProductsListView extends StatefulWidget {
  const ProductsListView({
    Key key,
    @required this.productsInfosList,
  }) : super(key: key);

  final List<ProductInfosModels> productsInfosList;

  @override
  State<ProductsListView> createState() => _ProductsListViewState();
}

class _ProductsListViewState extends State<ProductsListView> {
  bool flagForCircularProgressIndicator = false;

  @override
  Widget build(BuildContext context) {
    return flagForCircularProgressIndicator
        ? Center(child: CircularProgressIndicator())
        : ListView.separated(
            itemBuilder: (BuildContext context, int index) {
              return InkWell(
                onTap: () async {
                  setState(() {
                    flagForCircularProgressIndicator = true;
                  });
                  await ProductsNetworking().downloadProductDocument(
                          widget.productsInfosList[index].productId.toString());
                  setState(() {
                    flagForCircularProgressIndicator = false;
                  });
                },
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(8, 25, 8, 25),
                  child: Row(
                    children: [
                      Padding(
                        padding: const EdgeInsets.only(right: 8.0),
                        child: Container(
                          width: 140,
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: [
                              Icon(FontAwesomeIcons.scaleBalanced),
                              SizedBox(height: 15),
                              Text(widget.productsInfosList[index].id),
                            ],
                          ),
                        ),
                      ),
                      Expanded(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(widget.productsInfosList[index].productName),
                            SizedBox(height: 10.0),
                            Text(widget.productsInfosList[index].productionDate),
                            SizedBox(height: 10.0),
                          ],
                        ),
                      ),
                      Container(
                        width: 60,
                        child: Icon(Icons.download))
                    ],
                  ),
                ),
              );
            },
            separatorBuilder: (BuildContext context, int index) =>
                const Divider(
              color: Colors.black54,
            ),
            itemCount: widget.productsInfosList.length,
          );
  }
}

Я не вижу, где productsInfosList обновляется. И это должно быть в штате.

Patrick 17.05.2024 16:28

Я думаю, что более серьезная проблема заключается в том, как переключаться между индикатором прогресса и списком. Либо оберните только наш список в собственный виджет с состоянием, либо поместите индикатор загрузки в стек.

Thomas 17.05.2024 18:54

@Patrick Я обновляю список продуктовInfosList в улучшенном виджете.

Aaydin 20.05.2024 08:36

@Thomas Я показываю круговой индикатор прогресса, когда flagForCircularProgressIndicator имеет значение true, в противном случае показываю список. И круговой индикатор прогресса, и список уже используются в виджете с отслеживанием состояния.

Aaydin 20.05.2024 08:42

Да, но проблема в том, что сам список не находится внутри StatefulWidget, что означает, что когда вы меняете флагForCircularProgressIndicator на true, ваш ListView уничтожается и его необходимо воссоздать при повторном изменении флага.

Thomas 20.05.2024 10:00

@Thomas Вы имеете в виду, что просмотр списка уничтожается, потому что он не имеет состояния, верно?

Aaydin 26.05.2024 10:51

да, оберните это в другой виджет с состоянием

Thomas 26.05.2024 11:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я достиг своей цели. Я могу отслеживать положение пользователя в списке перед загрузкой, используя PageStorageKey. Я назначаю ключ своему списку, как показано ниже:

...
ListView.separated(
        key: PageStorageKey<String>('productsListView'),
        itemBuilder: (BuildContext context, int index) {
          return InkWell(
...

Вы можете прочитать замечательную статью Эмили Фортуны о ключах: Ключи! Чем они хороши?

Другие вопросы по теме