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

Flutter中如何在百分比指示器完成时显示弹窗

实现方法

可以通过监听AnimationController的状态变化,或者直接判断进度值,在进度达到100%时触发弹窗,以下是具体实现方案:

方案一:监听动画完成状态(适合一次性动画完成的场景)

如果你的进度是通过CircularPercentIndicator的动画一次性从0到100%,可以给控制器添加状态监听器,在动画完成时弹出对话框:

1. 添加状态监听与弹窗逻辑

在State类的initState方法中绑定监听器,同时在dispose中移除避免内存泄漏:

bool _hasTriggeredDialog = false;

@override
void initState() {
  super.initState();
  controller.addStatusListener(_checkAnimationStatus);
}

@override
void dispose() {
  controller.removeStatusListener(_checkAnimationStatus);
  controller.dispose();
  super.dispose();
}

void _checkAnimationStatus(AnimationStatus status) {
  // 避免重复弹窗
  if (status == AnimationStatus.completed && !_hasTriggeredDialog) {
    _hasTriggeredDialog = true;
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text("进度完成"),
        content: const Text("当前进度已达到100%!"),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text("确定"),
          ),
        ],
      ),
    );
  }
}

2. 保留原build方法

你的原build代码无需大幅修改,直接配合监听器即可:

@override
Widget build(BuildContext context) {
  var progressValue = (100 * controller.value).toInt();
  return FittedBox(
    child: CircularPercentIndicator(
      percent: controller.value,
      animation: true,
      animationDuration: 1000,
      progressColor: colorProgressIndicatorProgress,
      radius: widget.radius,
      center: Text(
        "$progressValue% ${widget.centerText}",
        textAlign: TextAlign.center,
      ),
    ),
  );
}

方案二:直接判断进度值(适合逐步更新进度的场景)

如果进度是通过手动更新controller.value逐步推进的,可以在build方法中实时检查进度,达到100%时触发弹窗:

bool _hasShownDialog = false;

@override
Widget build(BuildContext context) {
  var progressValue = (100 * controller.value).toInt();
  
  // 检查进度是否达标且未弹窗
  if (controller.value >= 1.0 && !_hasShownDialog) {
    _hasShownDialog = true;
    // 使用addPostFrameCallback避免build过程中直接修改UI状态
    WidgetsBinding.instance.addPostFrameCallback((_) {
      showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: const Text("进度完成"),
          content: const Text("当前进度已达到100%!"),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text("确定"),
            ),
          ],
        ),
      );
    });
  }

  return FittedBox(
    child: CircularPercentIndicator(
      percent: controller.value,
      animation: true,
      animationDuration: 1000,
      progressColor: colorProgressIndicatorProgress,
      radius: widget.radius,
      center: Text(
        "$progressValue% ${widget.centerText}",
        textAlign: TextAlign.center,
      ),
    ),
  );
}

内容的提问来源于stack exchange,提问作者gregory jithin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:27:30