1

我正在构建这个纸牌游戏应用程序,它有一个卡片列表(具有特殊效果的容器),并且该列表由提供者/消费者机制管理和更新。

看起来像这样 在此处输入图像描述

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% 确定 Consumer 已使用新数据进行了更新,因为 build 方法中的 print 语句会打印新添加的卡片。

最后,问题是 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() 但我没有任何地方可以从我的 listView 中调用 Setstate。

我尝试用 Provider.of(context).playerlist[0].ownlist 等替换 ownList 逻辑,但这也不起作用

我希望我已经为这次评估提供了足够的数据。如果需要更多信息,请发表评论。非常感谢您的时间和建议。

4

1 回答 1

1

我阅读了有关该问题的更多信息,有帮助的来源是

基本上我的列表正在更新,但我提供了数组的引用,并且由于颤动适用于不可变数据,它没有检测到我的数组更改。所以我所要做的就是从现有的参考数组中构建一个新列表。

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(),);
  }
}

现在我的纸牌游戏正在用新牌更新!!

于 2020-05-17T05:18:02.933 回答