You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何实现列表构建器内单个TimerButton独立触发OTP重发

解决TimerButton在列表中批量禁用的问题

这个问题我太熟悉了!你现在遇到的情况,本质是所有列表项里的TimerButton共享了同一个父组件的状态——当你调用setState()时,整个列表会被重建,导致所有TimerButton都同步进入了倒计时禁用状态。

要解决这个问题,核心思路是给每个列表项单独维护自己的状态,具体步骤如下:

1. 将列表项抽为独立的StatefulWidget

把包含TimerButton的列表项拆成一个单独的StatefulWidget,这样每个列表项都会拥有自己独立的状态管理,不会互相干扰。

示例代码如下:

class TransactionItem extends StatefulWidget {
  final String invoiceNumber;
  final Color appbarColor;
  // 可根据需求传递其他必要参数

  const TransactionItem({
    Key? key,
    required this.invoiceNumber,
    required this.appbarColor,
  }) : super(key: key);

  @override
  State<TransactionItem> createState() => _TransactionItemState();
}

class _TransactionItemState extends State<TransactionItem> {
  @override
  Widget build(BuildContext context) {
    return TimerButton(
      buttonType: ButtonType.RaisedButton,
      label: "Resend OTP",
      timeOutInSeconds: 10,
      onPressed: () {
        // 此处的setState仅更新当前TransactionItem的状态,不会影响其他列表项
        setState(() {
          ResendOTP(widget.invoiceNumber);
        });
      },
      disabledColor: Colors.grey,
      color: widget.appbarColor,
      disabledTextStyle: const TextStyle(fontSize: 15.0),
      activeTextStyle: const TextStyle(fontSize: 15.0, color: Colors.white),
    );
  }
}

2. 在原列表中使用这个子组件

把原来列表里直接写TimerButton的地方,替换成这个TransactionItem组件:

// 假设你原来的列表是基于ListView.builder实现的
ListView.builder(
  itemCount: snapshot.data?.length ?? 0,
  itemBuilder: (context, index) {
    return TransactionItem(
      invoiceNumber: snapshot.data![index].invoiceNumber,
      appbarColor: appbarColor,
      // 传递其他需要的参数
    );
  },
)

为什么这样有效?

每个TransactionItem都有自己独立的State对象,当你点击某个按钮调用setState()时,只会触发当前TransactionItem的UI重建,而不会影响列表中的其他项。这样就实现了只有被点击的TimerButton进入倒计时禁用状态,其他按钮保持正常可用的效果。

内容的提问来源于stack exchange,提问作者Antonio Ceasar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 08:34:06