赞
踩
目录
Flutter中的隐式动画指的是通过使用Flutter的动画库,就可以创建各种炫酷的UI视觉效果。 我们可以使用库中的一套组件来管理动画,这些组件被称为隐式动画组件。隐式动画组件都实现了ImplicitlyAnimatedWidget类,这些隐式动画组件有个共同的特点就是组件都以Aanimated为前缀。使用隐式动画,我们只需要关注动画的初始值和最终值,而不需要做额外的处理,这给我们的工作带来了很大的方便。
这里写了一个效果图,先通过小面的效果图看下隐式动画能实现哪些炫酷的UI视觉效果,然后在看看Flutter中常用的隐式动画组件。
图1.AnimatedWidget动画效果图
opacity即透明度,我们可以通过修改Widget的opacity值来实现动画的效果。可以看下图1实力中的第一个动画效果。这里随机生成了一个Container组件,然后每隔0.25s修改下Container的透明度。这里我们通过官方的文档来实现渐如效果。
AnimatedWidget的用法和Widget的用法基本相同,我们只需关注AnimatedWidget实现的ImplicitlyAnimatedWidget即可。
我们以下面的效果为例,看下AnimatedOpacity的用法。
图2.点击按钮显示图片详情
在图2中,我们点击显示图片简介的时候,显示图片的详细信息。点击隐藏的时候,隐藏图片的信息。关键代码如下:
- class _MyHomePageState extends State<MyHomePage> {
- double opacity = 0;
- bool showDetail = false;
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- backgroundColor: Theme.of(context).colorScheme.inversePrimary,
- title: Text(widget.title),
- ),
- body: Center(
- // Center is a layout widget. It takes a single child and positions it
- // in the middle of the parent.
- child: Column(children: <Widget>[
- const Image(image: AssetImage('images/opacity.png'),width: 480,height: 270,),
- TextButton(
- child: Text(
- opacity == 0 ?'显示图片简介':'隐藏图片简介',
- style: const TextStyle(color: Colors.blueAccent),
- ),
- onPressed: () => setState(() {
- if(opacity == 0){
- opacity = 1;
- }else{
- opacity = 0;
- }
- }),
- ),
- opacity ==0 ? const SizedBox():const Column(
- children: [
- Text('图片作者: 柱子哥',),
- Text('图片拍摄地点: 上海'),
- Text('图片分辨率: 480 * 270'),
- ],
- )
- ]),
- ), // This trailing comma makes auto-formatting nicer for build methods.
- );
- }
- }
上述的代码非常简单,我们通过一个标记为来控制图片信息的显示和隐藏。显示的视觉鲜果没有动画,稍微显得有点生硬,我们看一下如何给图片简介信息添加动画效果。当我们点击显示图片简介信息的时候,1秒种之后,简介信息的透明度从0到1逐渐变化。这个时候AnimatedOpactity就派上了用场。
AnimatedOpactity的用法也很简单,我们只需要把要处理的Widget包裹起来即可。
这里我们只需要AanimatedOpacity的opacity属性和duration属性。AnimatedOpacity会根据我们设置的参数自动处理动画。再上述的demo中,我们把标志位设置为AnimatedOpacity的opacity属性,duration设置为1s,就会产生一个动画效果。效果图如下:
图3.AnimatedOpacity动画效果
我们看一下AnimatedOpacity的定义:
const AnimatedOpacity({
super.key,
this.child,
required this.opacity,
super.curve,
required super.duration,
super.onEnd,
this.alwaysIncludeSemantics = false,
}) : assert(opacity >= 0.0 && opacity <= 1.0);
我们还可以通过curve属性定义动画变化的曲线,默认是Curves.linear(线性动画),设置onEnd来配置动画完成之后的回调函数。
AnimatedPadding和Padding用法大致相同,我们可以通过改变padding属性,移动Widget,达到动画的效果。
这里有两个属性padding和duration。其中padding为间距,duration为动画时长。下面的例子中,我们通过一个定时器,不断的修改padding属性,做了一个闪光灯的效果。
图4.粗糙的闪光灯效果
AnimatedPositioned动画就是通过修改Positon的top,bottom,left,right属性来修改Widget的位置,产生一个动画效果。这里AanimatedPositioned的用法和AnimatedPadding用法类似,这里就不做赘述了。下面也写了一个动画效果,点击移动小球之后,小球每次左移50个单位。
图5.AnimatedPositioned动画
AnimatedSwitcher用来切换两个不同的组件。
这里需要注意的是当我们切换组件的时候,我们需要为旧的组件和新的Widget设置一个不同的key,动画效果才会生效。这种动画应用也挺广泛的,例如我们在使用微信和支付宝付款的时候,付款完成之后就会有一个完成的动画。
图6.AnimatedSwitcher动画效果
关键代码如下:
- class _MyHomePageState extends State<MyHomePage> {
- bool isCompleted = false;
- int keyValue = 0;
-
- Widget completedWidget(){
- return GestureDetector(
- key: ValueKey<int>(keyValue),
- child: Container(
- width: 100,
- height: 40,
- alignment: Alignment.center,
- decoration: const BoxDecoration(
- color: Colors.black12,
- borderRadius: BorderRadius.all(Radius.circular(20))
- ),
- child: const Text('点击完成',style: TextStyle(fontSize: 12,fontWeight: FontWeight.bold),),
- ),
- onTap: (){
- setState(() {
- keyValue++;
- isCompleted = !isCompleted;
- });
- },
- );
- }
- Widget normalWidget(){
- return GestureDetector(
- key: ValueKey<int>(keyValue),
- child: Container(
- width: 50,
- height: 50,
- alignment: Alignment.center,
- decoration: const BoxDecoration(
- color: Colors.green,
- borderRadius: BorderRadius.all(Radius.circular(25))
- ),
- child: const Icon(Icons.check),
- ),
- onTap: (){
- setState(() {
- keyValue++;
- isCompleted = !isCompleted;
- });
- },
- );
- }
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- backgroundColor: Theme.of(context).colorScheme.inversePrimary,
- title: Text(widget.title),
- ),
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- AnimatedSwitcher(
- duration: const Duration(milliseconds: 2000),
- child: isCompleted?completedWidget():normalWidget(),
- ),
- ],
- ),
- ), // This trailing comma makes auto-formatting nicer for build methods.
- );
- }
- }
AnimatedAlign通过修改子类Widget的位置实现UI动画效果。用法也比较简单,这里也写了一个小球移动类似于贪吃蛇的效果。效果图如下,我们结合一个计时器不停的修改AnimatedAlign的padding即可。
图7.AnimatedAlign动画效果
Flutter中的Container是一个容器,有着非常多的属性,因此我们可以使用AnimatedContainer可以实现非常多的动画效果。
例如下面这个来自官网的例子中,我们可以修改Widget和颜色和圆角,实现Widget形状的变化动画效果。
图8.AnimatedContainer实现的各种动画效果
上面的AnimatedWidget实现的动画效果我们都是通过设置参数来实现的,当然我们也可以自定义动画效果。这个时候AnimatedBuilder就派上用场了。例如我们要实现一个如下图所示的Widget的旋转动画效果。
图9.AnimatedBuilder动画效果
在使用AnimatedBuilder的时候,有两个参数,animation和builder。
其中animation用来定义动画的类型
builder是一个回调函数,在回调函数中我们配置要做动画的Widget和使用的动画类型。
当然这里如果要使用AnimatedBuilder要继承自SingleTickerProviderStateMixin。
主要的代码如下:
- class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
- late Animation<num> animation ;
- late AnimationController controller;
-
- @override
- void initState() {
- super.initState();
- controller = AnimationController(
- duration: const Duration(seconds: 4),
- vsync: this)..repeat();
- animation = Tween(begin: 0,end: 2 * pi).animate(controller);
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- backgroundColor: Theme.of(context).colorScheme.inversePrimary,
- title: Text(widget.title),
- ),
- body: Center(
- child: Container(
- alignment: Alignment.center,
- child: AnimatedBuilder(animation: animation, builder: (BuildContext context, Widget? child) {
- return Transform.rotate(
- angle: animation.value.toDouble(),
- child: Container(
- color: Colors.deepOrange,
- width: 200,
- height: 200,
- alignment: Alignment.center,
- child: const Text('AnimatedBuilder动画',style: TextStyle(fontSize: 14,fontWeight: FontWeight.bold,),textAlign: TextAlign.center,),
- ),
- );
- },
- ),
- ),
- ), // This trailing comma makes auto-formatting nicer for build methods.
- );
- }
- }
AnimatedSize可以通过修改width和height属性实现动画效果。
例如下面的UI动画效果,我们点击按钮的时候,Widget的高度和宽度都增加50,这样就实现了放大的动画效果。
图10.AnimatedSize动画效果
隐式动画写到这里,基本上也差不多了,总结下AnimatedWidget的用法和Widget基本相似,我们只需要关注AnimatedWidget的旧的属性值和新的属性值,然后通过配置参数就可以实现各种酷炫的UI视觉效果,当然我们可以通过AnimatedBuilder来实现动画的自定义。更多的AnimatedWidget的用法以后再更新吧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。