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

Flutter:如何自定义数据加载时颜色交替切换的Container

实现加载时循环切换颜色的Container组件

这里提供一种基于Flutter动画系统的实现方案,能让Container在加载状态下自动在深灰、浅灰之间以1秒间隔切换,加载完成后停止动画:

完整实现代码

import 'package:flutter/material.dart';

class LoadingSwitchColorContainer extends StatefulWidget {
  final Widget child;
  final bool isLoading;
  final Color normalColor;
  final Color darkGrey;
  final Color lightGrey;

  const LoadingSwitchColorContainer({
    super.key,
    required this.child,
    required this.isLoading,
    this.normalColor = Colors.transparent,
    this.darkGrey = const Color(0xFF333333),
    this.lightGrey = const Color(0xFFAAAAAA),
  });

  @override
  State<LoadingSwitchColorContainer> createState() => _LoadingSwitchColorContainerState();
}

class _LoadingSwitchColorContainerState extends State<LoadingSwitchColorContainer> with SingleTickerProviderStateMixin {
  late AnimationController _animController;
  late Animation<Color?> _colorAnim;

  @override
  void initState() {
    super.initState();
    // 初始化1秒时长的动画控制器
    _animController = AnimationController(
      duration: const Duration(seconds: 1),
      vsync: this,
    );
    // 绑定深灰到浅灰的颜色过渡动画
    _colorAnim = ColorTween(
      begin: widget.darkGrey,
      end: widget.lightGrey,
    ).animate(_animController);
    
    // 如果初始处于加载状态,启动循环动画
    if (widget.isLoading) {
      _animController.repeat(reverse: true);
    }
  }

  @override
  void didUpdateWidget(covariant LoadingSwitchColorContainer oldWidget) {
    super.didUpdateWidget(oldWidget);
    // 加载状态变化时,自动启动/停止动画
    if (widget.isLoading != oldWidget.isLoading) {
      widget.isLoading 
          ? _animController.repeat(reverse: true) 
          : _animController.stop();
    }
  }

  @override
  void dispose() {
    // 销毁动画控制器,避免内存泄漏
    _animController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      duration: const Duration(seconds: 1),
      // 加载状态用动画颜色,否则用默认颜色
      color: widget.isLoading ? _colorAnim.value : widget.normalColor,
      child: widget.child,
    );
  }
}

// 使用示例
class DemoPage extends StatefulWidget {
  const DemoPage({super.key});

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

class _DemoPageState extends State<DemoPage> {
  bool _loading = true;

  @override
  void initState() {
    super.initState();
    // 模拟3秒的数据加载过程
    Future.delayed(const Duration(seconds: 3), () {
      setState(() => _loading = false);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: LoadingSwitchColorContainer(
        isLoading: _loading,
        child: const Center(child: Text('加载中...')),
      ),
    );
  }
}

关键说明

  • 利用AnimationController的repeat(reverse: true)方法,实现颜色在深灰、浅灰之间的循环过渡,周期为1秒
  • 通过isLoading参数控制动画启停,加载完成后自动切换到自定义的默认颜色
  • 支持自定义默认色、深灰色、浅灰色,适配不同UI场景需求
  • 监听didUpdateWidget方法,确保加载状态动态变化时动画能正确响应
  • 组件销毁时释放动画控制器,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:05:16