维护有状态小部件(进度条)问题的Listview.Builder()中的状态

时间:2019-10-24 23:12:24

标签: flutter

我正在使用listview.builder创建一个listview。每个视图都是一张带有按钮和进度条的卡片(请参见屏幕截图) enter image description here

每张卡都是有状态的小部件。当您按下按钮时,进度条将启动一个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: (){},
          );
    }),
    );

错误记录: enter image description here

1 个答案:

答案 0 :(得分:1)

现在工作。 好吧,我想我知道发生了什么事。整个有状态小部件都将被处置和重建,结果,有状态小部件的“逻辑”“内部”也被重置。我所做的是:

1)在“对象”中添加了几个额外的变量 2)当再次构建视图时,它将检查这些变量,然后“恢复”上次放置的状态,其中包括进度条计数器的值。

为避免这种情况发生,整个逻辑从onTap()中取出,并添加到了新的异步方法中。

Simplessss :)