更新基础列表时,Flutter ListView 不会更新
Flutter ListView doesnt update when the underlying list is updated
我正在构建这个纸牌游戏应用程序,它有一个纸牌列表(具有特殊效果的容器)并且该列表由 Provider/Consumer 机制管理和更新。
看起来像这样
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 更新了新数据,因为构建方法中的 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 逻辑,但这也不起作用
我希望我已经为这次评估提供了足够的数据。如果需要更多信息,请发表评论。非常感谢您的时间和建议。
我阅读了有关该问题的更多信息,有用的来源是
基本上我的列表正在更新,但我提供了数组的引用,并且由于 flutter 适用于不可变数据,因此它没有检测到我的数组更改。所以我所要做的就是从现有的参考数组构建一个新列表。
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(),);
}
}
现在我的纸牌游戏正在更新新纸牌!!
我正在构建这个纸牌游戏应用程序,它有一个纸牌列表(具有特殊效果的容器)并且该列表由 Provider/Consumer 机制管理和更新。
看起来像这样
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 更新了新数据,因为构建方法中的 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 逻辑,但这也不起作用
我希望我已经为这次评估提供了足够的数据。如果需要更多信息,请发表评论。非常感谢您的时间和建议。
我阅读了有关该问题的更多信息,有用的来源是
基本上我的列表正在更新,但我提供了数组的引用,并且由于 flutter 适用于不可变数据,因此它没有检测到我的数组更改。所以我所要做的就是从现有的参考数组构建一个新列表。
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(),);
}
}
现在我的纸牌游戏正在更新新纸牌!!