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

Flutter实现文本值变化时背景闪烁的自定义Widget

Flutter 实现文本变化时背景闪烁的自定义Widget

可以用AnimationController配合AnimatedContainer来实现这个效果,比Timer.periodic更贴合Flutter的动画系统,下面是完整的实现代码:

import 'package:flutter/material.dart';

class FlashTextWidget extends StatefulWidget {
  final String text;
  final TextStyle? textStyle;
  final Color normalBackgroundColor;
  final Color flashColor;
  final int flashCount; // 闪烁次数
  final Duration flashDuration; // 单次闪烁时长

  const FlashTextWidget({
    super.key,
    required this.text,
    this.textStyle,
    this.normalBackgroundColor = Colors.transparent,
    this.flashColor = Colors.yellow,
    this.flashCount = 2,
    this.flashDuration = const Duration(milliseconds: 300),
  });

  @override
  State<FlashTextWidget> createState() => _FlashTextWidgetState();
}

class _FlashTextWidgetState extends State<FlashTextWidget> with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  late Animation<Color?> _colorAnimation;
  String _currentText = '';

  @override
  void initState() {
    super.initState();
    _currentText = widget.text;
    _initAnimation();
  }

  void _initAnimation() {
    _animationController = AnimationController(
      vsync: this,
      duration: widget.flashDuration,
    );

    // 定义颜色切换动画:正常色 ↔ 闪烁色
    _colorAnimation = ColorTween(
      begin: widget.normalBackgroundColor,
      end: widget.flashColor,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Curves.easeInOut,
    ));
  }

  @override
  void didUpdateWidget(covariant FlashTextWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    // 当文本发生变化时,触发闪烁动画
    if (oldWidget.text != widget.text) {
      _currentText = widget.text;
      _startFlashAnimation();
    }
  }

  void _startFlashAnimation() async {
    // 重置动画控制器
    _animationController.reset();
    // 重复指定次数的闪烁(一次完整的闪烁是:正常→高亮→正常)
    for (int i = 0; i < widget.flashCount; i++) {
      await _animationController.forward();
      await _animationController.reverse();
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      duration: widget.flashDuration,
      color: _colorAnimation.value,
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
      child: Text(
        _currentText,
        style: widget.textStyle,
      ),
    );
  }
}

使用示例

在页面中直接调用这个自定义Widget,传入文本即可:

class DemoPage extends StatefulWidget {
  const DemoPage({super.key});

  @override
  State<DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  String _displayText = '初始文本';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            FlashTextWidget(
              text: _displayText,
              textStyle: const TextStyle(fontSize: 20),
              flashColor: Colors.lightBlue,
              flashCount: 3,
            ),
            const SizedBox(height: 40),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  _displayText = '更新后的文本${DateTime.now().second}';
                });
              },
              child: const Text('切换文本'),
            ),
          ],
        ),
      ),
    );
  }
}

关键说明

  • 通过didUpdateWidget监听文本参数的变化,触发闪烁逻辑
  • 用AnimationController和ColorTween实现平滑的颜色过渡,比Timer更流畅
  • 可自定义闪烁颜色、次数、时长,适配不同场景
  • 记得在dispose中销毁动画控制器,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 00:55:18