Flutter ListView не обновляется при обновлении базового списка

Я создаю это приложение для карточной игры, в котором есть список карт (контейнеров со специальными эффектами), и этот список управляется и обновляется механизмом поставщика/потребителя.

Выглядит это так: .png" alt="введите здесь описание изображения">

class LowerSectionWithScrollingCardList extends StatefulWidget {
  @override
  _LowerSectionWithScrollingCardListState createState() =>
      _LowerSectionWithScrollingCardListState();
}

class _LowerSectionWithScrollingCardListState
    extends State<LowerSectionWithScrollingCardList> {

  @override
  Widget build(BuildContext context) {
    return Consumer<GameState>(builder: (context, gameState, child) {
      print('lower list ${gameState.gcurrentPlayers[0].ownList}');
      return Expanded(
        flex: 34,
        child: Container(
          color: Colors.white,
          child: ListView(
            children: gameState.gcurrentPlayers[0].ownList,
            scrollDirection: Axis.horizontal,
          ),
        ),
      );
    });
  }
}

gameState.gcurrentPlayers[0].ownList — это первый игрок, которым мы являемся, а ownlist — это фактический список виджетов или карточек, который обновляется при нажатии некоторых других кнопок в приложении.

список обновляется именно этим методом

void ggiveCardToCurrentPlayer(int howMuch){
    for(int i=0;i<howMuch;i++)
      ggetPlayerWithCurrentTurn().ownList.add(gplayingCards.removeLast());
    notifyListeners();
  }

Теперь, после вызова «notifylisteners», я на 100% уверен, что Потребитель обновлен новыми данными, потому что оператор печати в методе сборки печатает новые добавленные карты.

Наконец, проблема заключается в том, что сам listView не обновляется, в то время как отображаемый им список содержит эти добавленные карты.

Я просмотрел несколько сообщений по аналогичной проблеме, и они предлагают добавить ключи к элементам данных, в моем случае элементами данных являются мои карты, и я добавил к ним ключи. Без изменений.

class RegularUnoCard extends StatelessWidget{
  final Color _color;
  final String _value;
  final Key _key;
  RegularUnoCard(this._color, this._value,this._key);

@override
  Widget build(BuildContext context) {
    return Container(
      key: _key,
      margin: EdgeInsets.symmetric(
          vertical: _cardMarginVer, horizontal: _cardMarginHor),
      padding: EdgeInsets.all(15),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(_cardCornerRadii),
        border: Border.all(color: _color, width: 4, style: BorderStyle.solid),
        boxShadow: [
          BoxShadow(
              color: _color,
              spreadRadius: (_value == plus2) ? 8 : 2,
              blurRadius: 5)
        ],
        color: Colors.white,
      ),
      child: Container(
        height: _cardHeight,
        width: _cardWidth,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(60),
          color: _color,
        ),
        child: Center(
          child: getLogo(),
        ),
      ),
    );
  }

Я надеюсь, что это правильный способ положить ключи в карты.

Я также читал, что нужно вызывать setState(), но у меня нет места для вызова Setstate из моего listView.

Я попытался заменить логику ownList на Provider.of(context).playerlist[0].ownlist и т.д. и т.д., но это тоже не работает

Я надеюсь, что предоставил достаточно данных для этой оценки. Пожалуйста, прокомментируйте, если требуется дополнительная информация. Большое спасибо за ваше время и предложения.


person Lakshay Dutta    schedule 16.05.2020    source источник


Ответы (1)


Я прочитал больше о проблеме, источник, который был полезен, был this

В основном мой список обновлялся, но я предоставлял ссылку на массив, и, поскольку флаттер работает с неизменяемыми данными, он не обнаружил изменения моего массива. Так что все, что мне нужно было сделать, это построить новый список из существующего массива ссылок.

children: List<Widget>.from(gameState.gcurrentPlayers[0].ownList),

Окончательный ListView должен выглядеть так

@override
  Widget build(BuildContext context) {
    return Consumer<GameState>(builder: (context, gameState, child) {
      print('lower list ${gameState.gcurrentPlayers[0].ownList}');
      return Expanded(
        flex: 34,
        child: Container(
          color: Colors.white,
          child:ListView(
            children: List<Widget>.from(gameState.gcurrentPlayers[0].ownList),
            scrollDirection: Axis.horizontal,
          ),
        ),
      );
    },key: UniqueKey(),);
  }
}

Теперь моя карточная игра пополняется новыми картами!!

person Lakshay Dutta    schedule 17.05.2020