【发布时间】:2019-10-24 23:12:24
【问题描述】:
我正在使用 listview.builder 创建一个列表视图。每个视图都是一张卡片,上面有一个按钮和一个进度条(见截图)
每张卡片都是一个有状态的小部件。当您按下按钮时,进度条会启动 5 秒计时器。当计时器结束时,对象会从 LinkedHashMap 中移除,这也会从屏幕上消失。如果在显示的列表中仅按下一个按钮,则此方法有效。如果按下一个按钮并在 2 秒后按下第二个或/和第三个按钮,则可以在所有三个按钮上看到进度条的动画,但是一旦第一个按钮从屏幕上消失,第二个和子序列就会出现重新绘制后,它们会处于松散状态,并且看起来好像它们的按钮从未被按下过。
我想要做的是,保持它们的状态独立并保持它们的动画独立。当一张卡片消失时,其他卡片会相应地向上/向下移动,但进度动画会继续保持当前状态,它们似乎会在未按下/原始状态下重新绘制自己。
我的卡代码如下:
class _DeliveryCardsViewState extends State<DeliveryCardsView> {
double percentage = 1.0;
bool countdownStarted = false;
String buttonText = "CLAIM ORDER";
@override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
child: Container(
padding: EdgeInsets.only(top: 10.0, bottom: 10.0, left: 10.0, right: 10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text('#'+widget.delivery.uID),
GestureDetector(
onTap: () async {
if (!countdownStarted) {
countdownStarted = true;
setState(() {
buttonText = 'UNDO';
});
int j = 100;
while (j > 0) {
await Future.delayed(Duration(milliseconds: 50)); // Duration in seconds (50/10) = 5 seconds
j -= 1;
setState(() {
if (countdownStarted){
percentage = (j / 100).toDouble();
} else {
percentage = 1.0;
}
});
if (!countdownStarted){
setState(() {
buttonText = 'CLAIM ORDER';
});
break;
}
}
//Try to claim it now
if (countdownStarted) tryClaimOnFirebase();
} else {
countdownStarted = false;
}
},
child: Container(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
Text(buttonText,style: TextStyle(color: Colors.white),),
SizedBox(height: 5.0,),
LinearPercentIndicator(
width: 100.0,
lineHeight: 7.0,
percent: percentage,
backgroundColor: Colors.green,
progressColor: Colors.red,
),
],
),
decoration: BoxDecoration(
color: mainGrey,
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
)
),
],
),
],
),
),
);
}
而我的Listview.builder代码如下:
return Container(color: Colors.grey[350],
child: ListView.builder(
key: UniqueKey(),
itemCount: deliveriesAvailable.length,
controller: _controller,
scrollDirection: Axis.vertical,
reverse: false,
shrinkWrap: true,
itemBuilder: (context,position){
return GestureDetector(
child: DeliveryCardsView(delivery: deliveriesAvailable.values.elementAt(position),),
onTap: (){},
);
}),
);
【问题讨论】:
-
如何将
j声明为全局变量。每次状态更改时,它都会重建视图。所以每个字段都有初始值而不是当前值。您可以将其声明为全局字段或构造函数中的参数 -
谢谢。但这会解决问题,因为每个对象都有自己的“j”计数器。
标签: flutter