У меня есть виджет, который возвращает 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,
);
}
}
Я думаю, что более серьезная проблема заключается в том, как переключаться между индикатором прогресса и списком. Либо оберните только наш список в собственный виджет с состоянием, либо поместите индикатор загрузки в стек.
@Patrick Я обновляю список продуктовInfosList в улучшенном виджете.
@Thomas Я показываю круговой индикатор прогресса, когда flagForCircularProgressIndicator имеет значение true, в противном случае показываю список. И круговой индикатор прогресса, и список уже используются в виджете с отслеживанием состояния.
Да, но проблема в том, что сам список не находится внутри StatefulWidget, что означает, что когда вы меняете флагForCircularProgressIndicator на true, ваш ListView уничтожается и его необходимо воссоздать при повторном изменении флага.
@Thomas Вы имеете в виду, что просмотр списка уничтожается, потому что он не имеет состояния, верно?
да, оберните это в другой виджет с состоянием





Я достиг своей цели. Я могу отслеживать положение пользователя в списке перед загрузкой, используя PageStorageKey. Я назначаю ключ своему списку, как показано ниже:
...
ListView.separated(
key: PageStorageKey<String>('productsListView'),
itemBuilder: (BuildContext context, int index) {
return InkWell(
...
Вы можете прочитать замечательную статью Эмили Фортуны о ключах: Ключи! Чем они хороши?
Я не вижу, где
productsInfosListобновляется. И это должно быть в штате.