Flutter Loading动画系列中最复杂的一个效果
老孟Flutter
共 7381字,需浏览 15分钟
· 2021-10-14
Loading动画系列
github地址:https://github.com/LaoMengFlutter/flutter-do
最复杂的效果
我个人认为最复杂的,也是花费时间最长的动画效果
放慢来看,是一个3x3的矩形,从左下角开始,每一斜排依次缩小,再还原的过程,下面就一步步实现,先绘制一个矩形:
class Square extends StatelessWidget {
final Color color;
const Square({Key? key,required this.color}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: color,
);
}
}
绘制3x3的矩形,并给每一个矩形添加 「ScaleTransition」 ,用于后面实现缩放
@override
Widget build(BuildContext context) {
return SizedBox.fromSize(
size: Size.square(widget.size),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_square(_anim3, 0),
_square(_anim4, 1),
_square(_anim5, 2),
],
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_square(_anim2, 3),
_square(_anim3, 4),
_square(_anim4, 5),
],
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_square(_anim1, 6),
_square(_anim2, 7),
_square(_anim3, 8),
],
),
],
),
);
}
Widget _square(Animation<double> animation, int index) {
return ScaleTransition(
scale: animation,
child: SizedBox.fromSize(
size: Size.square(widget.size / 3.0),
child: Square(
color: widget.color,
)),
);
}
重点来了,为什么需要5个 「Animation」 呢?因为共有5个斜排,同一个斜排使用一个Animation,如图:
其中1-5数字代表代码中的 _anim1, _anim2, _anim3, _anim4, _anim5,动画的效果都是依次缩小,再还原的过程,但1-2-3-4-5依次完成,并不是同时完成,代码如下:
_anim1 = TweenSequence([
TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 50),
TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 50),
]).animate(CurvedAnimation(
parent: _controller, curve: Interval(0.1, 0.6, curve: widget.curve)));
_anim2 = TweenSequence([
TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 50),
TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 50),
]).animate(CurvedAnimation(
parent: _controller, curve: Interval(0.2, 0.7, curve: widget.curve)));
_anim3 = TweenSequence([
TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 50),
TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 50),
]).animate(CurvedAnimation(
parent: _controller, curve: Interval(0.3, 0.8, curve: widget.curve)));
_anim4 = TweenSequence([
TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 50),
TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 50),
]).animate(CurvedAnimation(
parent: _controller, curve: Interval(0.4, 0.9, curve: widget.curve)));
_anim5 = TweenSequence([
TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 50),
TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 50),
]).animate(CurvedAnimation(
parent: _controller, curve: Interval(0.5, 1.0, curve: widget.curve)));
难点解决了,下面是完整的代码:
import 'package:flutter/material.dart';
///
/// desc:
///
class SquareGridScaleLoading extends StatefulWidget {
final double size;
final Duration duration;
final Curve curve;
final Color color;
const SquareGridScaleLoading(
{Key? key,
this.color = Colors.white,
this.size = 48.0,
this.duration = const Duration(milliseconds: 1500),
this.curve = Curves.linear})
: super(key: key);
@override
_SquareGridScaleLoadingState createState() => _SquareGridScaleLoadingState();
}
class _SquareGridScaleLoadingState extends State<SquareGridScaleLoading>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _anim1, _anim2, _anim3, _anim4, _anim5;
@override
void initState() {
_controller = AnimationController(vsync: this, duration: widget.duration)
..repeat();
_anim1 = TweenSequence([
TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 50),
TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 50),
]).animate(CurvedAnimation(
parent: _controller, curve: Interval(0.1, 0.6, curve: widget.curve)));
_anim2 = TweenSequence([
TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 50),
TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 50),
]).animate(CurvedAnimation(
parent: _controller, curve: Interval(0.2, 0.7, curve: widget.curve)));
_anim3 = TweenSequence([
TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 50),
TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 50),
]).animate(CurvedAnimation(
parent: _controller, curve: Interval(0.3, 0.8, curve: widget.curve)));
_anim4 = TweenSequence([
TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 50),
TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 50),
]).animate(CurvedAnimation(
parent: _controller, curve: Interval(0.4, 0.9, curve: widget.curve)));
_anim5 = TweenSequence([
TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 50),
TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 50),
]).animate(CurvedAnimation(
parent: _controller, curve: Interval(0.5, 1.0, curve: widget.curve)));
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox.fromSize(
size: Size.square(widget.size),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_square(_anim3, 0),
_square(_anim4, 1),
_square(_anim5, 2),
],
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_square(_anim2, 3),
_square(_anim3, 4),
_square(_anim4, 5),
],
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_square(_anim1, 6),
_square(_anim2, 7),
_square(_anim3, 8),
],
),
],
),
);
}
Widget _square(Animation<double> animation, int index) {
return ScaleTransition(
scale: animation,
child: SizedBox.fromSize(
size: Size.square(widget.size / 3.0),
child: Square(
color: widget.color,
)),
);
}
}
class Square extends StatelessWidget {
final Color color;
const Square({Key? key,required this.color}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: color,
);
}
}
最终的效果如下:
评论
多人同时导出 Excel 干崩服务器!新来的阿里大佬给出的解决方案太优雅了!
点击关注公众号,Java 干货及时推送↓推荐阅读:面试辅导,我们出大成果了!来源:juejin.cn/post/7259249904777838629前言 业务诉求:考虑到数据库数据日渐增多,导出会有全量数据的导出,多人同时导出可以会对服务性能造成影响,导出涉及到mysql查询的io操作,
Java技术栈
1
有意思!一个关于 Spring 历史的在线小游戏
发现 Spring One 的官网上有个好玩的彩蛋,分享给大家!进到Spring One的官网,可以看到右下角有个类似马里奥游戏中的金币图标。点击该金币之后,会打开一个新的页面,进入下面这样一个名为:The History Of Spring 的在线小游戏你可以使用上下左右的方向键来控制Spring
公众号程序猿DD
1
了解加密货币到加密货币的互换
1、什么是加密货币互换?加密货币到加密货币的互换是指以现行市场汇率将一种加密货币直接兑换为另一种加密货币。与需要法定货币存款和较长流程的传统交易所不同,加密货币到加密货币的互换可以无缝地促进交换。掉期在提高加密货币的流动性和效率方面发挥着重要作用。该功能使用户能够将他们的加密货币与钱包中的其他代币进
区块链头条
0
李彦宏:开源大模型不如闭源,后者会持续领先;周鸿祎:“开源不如闭源” 的言论是胡说八道
架构师大咖
架构师大咖,打造有价值的架构师交流平台。分享架构师干货、教程、课程、资讯。架构师大咖,每日推送。
公众号该公众号已被封禁0、李彦宏:开源大模型不如闭源,后者会持续领先当今
源码共读
0
用 Shader 实现旗帜飘扬动画效果
我觉得对于刚入门 3D 编程的朋友来说,如果能够完成代码创建模型数据->创建材质->编写Shader动画这一系列,想必会有满满的成就感。今天就用 Cocos Creator 的 utils.MeshUtils.createMesh 接口,带大家感受一下这个流程。这个流程不仅可以用于新手学
COCOS
2
【第129期】程序员的新宠:三款终端工具,让你告别Xshell!
概述 WindTerm:跨平台的SSH利器 首先介绍的是WindTerm,这是一款使用C语言开发的跨平台SSH客户端。它不仅完全免费,而且没有商业使用的限制。WindTerm支持SSH v2、Telnet、Raw Tcp等协议,而且性能出色,甚至超过了FinalShell和Electerm。功能
前端微服务
0
字节员工:35岁以后被裁员的,后来都走了哪条路?现在2-2,要不要利用最后一年拼命上个岸。
架构师大咖
架构师大咖,打造有价值的架构师交流平台。分享架构师干货、教程、课程、资讯。架构师大咖,每日推送。
公众号该公众号已被封禁在当今竞争激烈的职场环境中,年龄并不总是一个决定性
源码共读
0
顶级 Javaer 都在用的 20 个类库,真香!
点击关注公众号,Java 干货及时推送↓推荐阅读:投了 100 多份简历后…优秀且经验丰富的Java开发人员的特征之一是对API的广泛了解,包括JDK和第三方库。我花了很多时间来学习API,尤其是在阅读了Effective Java 3rd Edition之后 ,Joshua Bloch建
Java技术栈
1