当前位置: 首页 > news >正文

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆

    • 1. 定义 LoadingScreen 类
    • 2. 实现 _LoadingScreenState 类
    • 3. 定义 LoadingPainter 类
    • 4. 总结

实现加载动画

我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

效果展示视频地址:https://live.csdn.net/v/417383
资源文件下载地址:https://download.csdn.net/download/yang_6799/89639107

1. 定义 LoadingScreen 类

LoadingScreen 类是一个 StatefulWidget,它管理 AnimationController 和 Animation 对象。AnimationController 用于控制动画的播放,Animation 对象则表示动画的具体值。

import 'package:flutter/material.dart';
import 'dart:math';void main() => runApp(MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(home: LoadingScreen(),);}
}

以上代码定义了 MyApp 和 LoadingScreen 两个类,其中 MyApp 是应用的入口点,而 LoadingScreen 则是主要的动画屏幕。

2. 实现 _LoadingScreenState 类

在 LoadingScreen 类中,我们要实现 _LoadingScreenState,它是实际负责动画逻辑的地方。

class LoadingScreen extends StatefulWidget {@override_LoadingScreenState createState() => _LoadingScreenState();
}class _LoadingScreenState extends State<LoadingScreen>with SingleTickerProviderStateMixin {AnimationController? _controller;Animation<double>? _animation;@overridevoid initState() {super.initState();_controller = AnimationController(vsync: this,duration: Duration(seconds: 3),)..repeat();_animation = Tween<double>(begin: 0, end: 1).animate(_controller!);}@overridevoid dispose() {_controller?.dispose();super.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(backgroundColor: Colors.white,body: Center(child: CustomPaint(painter: LoadingPainter(animation: _animation!),child: SizedBox(width: 200.0,height: 200.0,),),),);}
}

详解

  • initState 方法:
    • 初始化时创建 AnimationController 并设置动画持续时间为 3 秒。
    • 调用 …repeat() 方法让动画重复播放。
    • 使用 Tween 创建一个从 0 到 1 的动画,并与控制器关联。
  • dispose 方法:
    • 销毁控制器以释放资源。
  • build 方法:
    • 使用 CustomPaint 来绘制自定义内容,这里我们指定了 LoadingPainter 作为画笔,然后设置了一个 200x200 的 SizedBox 来容纳绘制内容。

3. 定义 LoadingPainter 类

LoadingPainter 类继承自 CustomPainter,负责实际绘制每个小圆。我们需要计算每个小圆的位置、大小和透明度,以便实现顺时针方向依次从小到大的动画效果。

class LoadingPainter extends CustomPainter {final Animation<double> animation;LoadingPainter({required this.animation}) : super(repaint: animation);@overridevoid paint(Canvas canvas, Size size) {double radius = size.width / 2;int circleCount = 12;double baseCircleRadius = 5.0;double maxCircleRadius = 15.0;Paint paint = Paint()..style = PaintingStyle.fill;for (int i = 0; i < circleCount; i++) {double angle = (i / circleCount) * 2 * pi;double x = radius + radius * cos(angle);double y = radius + radius * sin(angle);// 计算每个小圆在动画中的进度,并加入相位偏移double progress = (animation.value - i / circleCount) % 1;double scaleFactor = (sin(progress * 2 * pi) + 1) / 2;double currentRadius =baseCircleRadius + scaleFactor * (maxCircleRadius - baseCircleRadius);// 确保透明度不低于 0.3double opacity = 0.3 + 0.7 * scaleFactor;paint.color = Colors.blue.withOpacity(opacity);canvas.drawCircle(Offset(x, y), currentRadius, paint);}}@overridebool shouldRepaint(covariant CustomPainter oldDelegate) {return true;}
}

详解

  • 构造函数:
    • 接受一个 Animation 类型参数,并调用 super(repaint: animation) 以便在动画值改变时触发重绘。
  • paint 方法:
    • 初始化一些常量,包括大圆的半径、小圆的数量以及小圆的最小和最大半径。
    • 使用 Paint 进行绘制配置。
    • 遍历每个小圆,并根据其序号和当前动画进度计算位置和大小。
    • 通过 sin 函数计算缩放因子 scaleFactor,并使用该因子调整小圆的半径和透明度。
    • 最后,通过 canvas.drawCircle 在计算出的坐标处绘制每个小圆。

4. 总结

在这篇文章中,我们学习了如何使用 Flutter 创建一个加载动画。通过 AnimationController 和 CustomPainter,我们可以轻松地实现各种复杂的动画效果。这种加载动画不仅可以提升用户体验,还可以让您的应用看起来更加专业。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • (每日一问)操作系统:常见的 Linux 指令详解
  • 人机交互与现代战争
  • 顺序表之创建,判满,插入,输出
  • 设计模式之状态模式 (C++ 实现)
  • 等级保护学习
  • 掏耳勺买哪种效果好?五大可视掏耳勺测评总汇
  • 前端:HTML、CSS、JS、Vue
  • 网络层ip协议
  • 单例的饿汉式,懒汉式的线程安全问题
  • 智能代码编辑器:Visual Studio Code的深度剖析
  • k8s--关于pod方面问题的排错思路与方法
  • .NetCore+vue3上传图片 Multipart body length limit 16384 exceeded.
  • redis常用知识汇总(包括 jedis 和 springboot 整合 redis)
  • Matlab自学笔记三十五:表table数据与外部文件的读入和写出
  • SpringBoot项目是如何启动
  • php的引用
  • JavaScript-如何实现克隆(clone)函数
  • [nginx文档翻译系列] 控制nginx
  • 0x05 Python数据分析,Anaconda八斩刀
  • canvas 五子棋游戏
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • django开发-定时任务的使用
  • Facebook AccountKit 接入的坑点
  • HTTP请求重发
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • Xmanager 远程桌面 CentOS 7
  • 代理模式
  • 技术胖1-4季视频复习— (看视频笔记)
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 入手阿里云新服务器的部署NODE
  • 在Mac OS X上安装 Ruby运行环境
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • postgresql行列转换函数
  • scrapy中间件源码分析及常用中间件大全
  • 积累各种好的链接
  • ​1:1公有云能力整体输出,腾讯云“七剑”下云端
  • ​卜东波研究员:高观点下的少儿计算思维
  • # C++之functional库用法整理
  • # centos7下FFmpeg环境部署记录
  • # 飞书APP集成平台-数字化落地
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (2)(2.10) LTM telemetry
  • (苍穹外卖)day03菜品管理
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (面试必看!)锁策略
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (五)关系数据库标准语言SQL
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (一)Docker基本介绍
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)