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

Flutter确定型LinearProgressBar数值变更后无动画效果如何解决

Flutter进度条分阶段动画不生效问题修复

问题根因

  • 初始化时重复声明了局部变量_originalValue、_newValue,导致初始绑定的补间动画固定为0→0的无效区间
  • 后续监听到Provider状态变更更新进度值后,没有同步更新补间动画的起止区间,动画一直沿用初始的无效配置
  • 每次触发新动画前没有重置动画控制器状态,首次执行完forward后,后续调用不会重新触发动画流程
  • 额外冗余的addListener监听,AnimatedBuilder已经实现了对动画控制器的状态监听,不需要额外调用setState刷新

修复后代码

import 'package:flutter/material.dart';
import 'package:learn_to_read/controllers/answerManager.dart';
import 'package:provider/provider.dart';

class AnswerProgressBar extends StatefulWidget {
  const AnswerProgressBar({Key? key}) : super(key: key);

  @override
  _AnswerProgressBarState createState() => _AnswerProgressBarState();
}

class _AnswerProgressBarState extends State<AnswerProgressBar>
    with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  late Animation<double> _anim;
  double _originalValue = 0;
  double _newValue = 0;
  late int _localPoints;
  late double _valueCompleted;

  @override
  void initState() {
    // 删掉重复声明的局部变量,直接使用类成员变量
    _animationController = AnimationController(
        duration: const Duration(milliseconds: 800), vsync: this);
    // 初始化补间动画
    _anim = Tween<double>(begin: _originalValue, end: _newValue)
        .animate(_animationController);
    _localPoints = 0;
    _valueCompleted = 0;
    super.initState();
  }

  @override
  void didChangeDependencies() {
    _originalValue = _newValue;
    final answerManager = Provider.of<AnswerManager>(context);
    if (answerManager.pageTilesCompleted &&
        _valueCompleted != 0) {
      _localPoints++;
    } else {
      _localPoints = answerManager.points;
    }
    _valueCompleted =
        _localPoints / answerManager.totalTilesPerPage;
    
    _newValue = _valueCompleted;
    // 同步更新补间动画的起止区间
    _anim = Tween<double>(begin: _originalValue, end: _newValue)
        .animate(_animationController);
    // 重置控制器后再执行动画
    _animationController.reset();
    _animationController.forward();
    
    super.didChangeDependencies();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    print('original value $_originalValue and new value $_newValue');
    return AnimatedBuilder(
      animation: _animationController,
      builder: (context, i) => LinearProgressIndicator(
        value: _anim.value,
        backgroundColor: Colors.grey
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 08:09:04