Flutter动画全解(三)底层自定义动画——Hero、CustomPainter和Rive

底层自定义动画 3.1 Flutter动画原理 ​ Flutter内部通过setState()函数刷新页面,且flutter优化得相当好,一秒执行60/120次也不会有卡顿。 ​ Ticker原理:屏幕每刷新一帧,称为一个ticker: Ticker _ticker = Ticker((elapsed) { print("Tick: $elapsed"); //elapsed是运行总时长 })..start(); ​ 你可以通过下列方式手动制作一个Ticker(仅作为实验用途,不推荐): double _height = 300; @override void initState(){ Ticker _ticker = Ticker((_) => setState((){ _height --; if(_height <= 0) _height = 300; }))..start(); super.initState(); } ​ 上述程序虽然可以运行,但首先,它没有考虑一些特殊情况,如程序暂时退出、切换到其他程序时,动画应该暂停。其次,每一帧时_height--,则在60帧的屏幕下该动画需要5秒执行完毕,而在120hz屏幕下只需要2.5秒。 3.2 Hero动画(主动画) ​ 将需要做Hero动画的控件包裹上Hero,并给它一个tag属性,两个页面对应控件的tag一致。 ​ 如果两个页面中的控件样式不一致,或者类型不统一,那么会瞬间切换,不会有控件切换时的动画效果。 3.3 CustomPaint ​ Tips:要使Container占满屏幕,使用 Container( constraints: BoxConstraints.expand(), //或者 width: double.infinity, height: double.infinity, ) 3.4 嵌入式Rive(Flare)插件动画 Rive New File

November 1, 2021 · 1 min · alvazu

Flutter动画全解(二)显式动画——Transition系列

显式动画——Transition系列(配合AnimationController) 2.1 循环旋转——RotationTransition ​ 我们需要使用RotationTransition配合AnimationController实现动画的手动控制,以实现隐式动画(Animated系列)无法完成的功能:循环重播、随时中断、多方协调等。 ​ 另外,要使用AnimationController,我们必须使用StatefulWidget,以使用生命周期函数initState()和dispose()。 ​ 我们先简单地看一个实例,在后文中,我们将详细解释其中的内容。 import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { MyApp({Key? key}) : super(key: key); @override _MyAppState createState() => _MyAppState(); } //SingleTickerProviderStateMixin用于垂直同步 class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { late AnimationController _controller; bool _loading = false; @override void initState() { _controller = AnimationController( duration: const Duration(seconds: 1), vsync: this, ); super.initState(); } @override void dispose() { _controller.dispose(); //用完删除,否则内存泄漏 super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: Container( width: 300, height: 120, color: Colors....

November 1, 2021 · 4 min · alvazu

Flutter动画全解(一)隐式动画——Animated系列

隐式动画——Animated系列 1.1 快速开始——AnimatedContainer //原始main.dart import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Container( //一个普普通通的Container width: 300, height: 300, color: Colors.blue, child: const Center( child: Text("Hi", style: TextStyle( fontSize: 72, )), ), ), )); } } //使用AnimatedContainer,并传入Duration,两行代码就可以动起来! import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: AnimatedContainer( //将Container换成AnimatedContainer duration: const Duration(seconds: 1), //同时加上duration参数即可 width: 300, height: 100, color: Colors....

November 1, 2021 · 3 min · alvazu