Flutter 高级动画技术综合指南

在动画领域,Flutter 提供了一系列功能,包括基于物理的动画,可以模拟真实世界的动态,在应用程序中创建更逼真和自然的运动。

本文将深入研究 Flutter 动画,探索各种类型,并演示如何在项目中实现它们。

Flutter 的动画系统围绕着一个“Animation 对象”的概念,这个对象的值会随着时间而变化,这个变化由一个“AnimationController”来控制,它定义了动画的持续时间、方向和其他参数,要设置一个动画,这两个元素必须连接起来。

常用的动画类

以下是在 Flutter 中创建动画时经常使用的一些关键类:

  • Tween:定义动画在其间进行插值的值范围。例如,它可以指定动画的开始值和结束值。
  • AnimationController:这个类控制动画进程,允许你启动、停止和重启动画,以及配置动画的持续时间和曲线。
  • AnimatedBuilder:这个小部件在动画发生变化时会重新构建自身,对于制作包含多个小部件的复杂动画特别有用。
  • Curve:Curve(曲线)决定了动画的进度,Flutter 提供了内置的曲线,如 LinearProgressIndicatorCurves.easeInOut ,或者你可以设计自己的自定义曲线。

基于物理的动画

Flutter 提供了 Simulation 类,用于创建具有初始状态和演化规则的基于物理的模拟,这个类使你能够制作各种基于物理的动画,包括基于弹簧动力学、摩擦力和重力的动画。

让我们考虑 Flutter 中基于物理的动画的示例:弹簧动画。 SpringSimulation 类可用于创建此动画,模拟阻尼谐振子。以下是如何使用 SpringSimulation 生成类似弹簧的动画:

// Import required packages
import 'package:flutter/material.dart';// 定义一个 SpringAnimation 小部件
class SpringAnimation extends StatefulWidget {const SpringAnimation({Key? key});_SpringAnimationState createState() => _SpringAnimationState();
}
class _SpringAnimationState extends State<SpringAnimation> with SingleTickerProviderStateMixin {late final AnimationController _controller = AnimationController(vsync: this,duration: const Duration(seconds: 3),)..forward();late final Animation<double> _animation = Tween<double>(begin: 0,end: 400,).animate(CurvedAnimation(parent: _controller,curve: Curves.elasticOut,));void _startAnimation() {_controller.reset();_controller.forward();}Widget build(BuildContext context) {return MaterialApp(home: Scaffold(body: Center(child: AnimatedBuilder(animation: _animation,builder: (context, child) {return Stack(children: [Positioned(left: 70,top: _animation.value,child: child!,)],);},child: GestureDetector(onTap: () {_startAnimation();},child: Container(height: 100,width: 250,decoration: BoxDecoration(color: const Color(0xFF00EF3C),borderRadius: BorderRadius.circular(10),),child: const Center(child: Text('SEMAPHORE',style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),)),),),),),),);}void dispose() {_controller.dispose();super.dispose();}
}

在这个例子中, SpringAnimation 小部件使用 AnimationController 来驱动 Animation 对象, Tween 定义了动画的值范围, CurvedAnimationCurves.elasticOut 赋予了动画一个弹性缓动曲线, AnimatedBuilder 小部件用于根据动画的值来动画 Container 小部件的位置, Positioned 小部件确保 Container 小部件在屏幕上的位置与动画的值相关,当小部件被构建时, AnimationController 启动了 Animation 对象的值动画,从而推动了 Container 小部件的位置动画。

结果是一个迷人的弹簧般的动画,在屏幕上产生弹跳效果。从本质上讲,基于物理的动画为您提供了一种强大的机制,可以在您的应用程序中制作逼真且流畅的动作,而 Flutter 提供了一系列工具和类来促进其实现。

Hero 动画

Flutter 中的 Hero 小部件充当不同屏幕之间共享元素转换的管道。例如,Hero 小部件可以以动画方式将小部件从一个屏幕过渡到另一个屏幕,包含图像、文本甚至容器等多种元素。该小部件通过为共享元素设置动画来促进无缝过渡。

Hero 小部件的一个关键方面是要求在起始和目标屏幕上都具有相同的标签,这个标签对于识别正在进行转换的共享元素至关重要。

考虑下面的示例,它演示了如何利用 Hero 小部件实现图像缩略图和全屏视图之间的平滑过渡。

缩略图屏幕

import 'package:flutter/material.dart';class ThumbnailScreen extends StatelessWidget {const ThumbnailScreen({super.key});Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('Thumbnail Screen'),),body: Column(children: [GridView.count(crossAxisSpacing: 15,crossAxisCount: 2,children: [Hero(tag: 'image1',child: GestureDetector(onTap: () {Navigator.push(context,MaterialPageRoute(builder: (context) => const FullScreenScreen(imageAsset: 'assets/white_puma.jpg',heroTag: 'image1',),),);},child: Image.asset('assets/white_puma.jpg'),),),Hero(tag: 'image2',child: GestureDetector(onTap: () {Navigator.push(context,MaterialPageRoute(builder: (context) => const FullScreenScreen(imageAsset: 'assets/red_nike.jpg',heroTag: 'image2',),),);},child: Image.asset('assets/red_nike.jpg',),),),],),],),);}
}

屏幕全屏

class FullScreenScreen extends StatelessWidget {final String imageAsset;final String heroTag;const FullScreenScreen({super.key, required this.imageAsset, required this.heroTag});Widget build(BuildContext context) {return Scaffold(body: GestureDetector(onTap: () {Navigator.pop(context);},child: Hero(tag: heroTag,child: Image.asset(imageAsset),),),);}
}

ThumbnailScreen 中,Hero 小部件封装了 Image 小部件,每个小部件都有一个独特的标签来区分共享元素。当用户与图像交互时,导航操作将他们引导到 FullScreenScreen

FullScreenScreen 中,图像被另一个 Hero 小部件包围,它与 ThumbnailScreen 中对应的图像具有相同的标签。这个标签控制着图像从缩略图屏幕到全屏显示的动画。此外,图像嵌套在一个GestureDetector中,使用户可以点击屏幕上的任何地方以恢复到缩略图屏幕。

当用户点击 ThumbnailScreen 上的图像时,Flutter 会编排一个动画,将共享元素传输到 FullScreenScreen 上。当用户点击 FullScreenScreen 上的图像时,Flutter 会执行一个动画,将共享元素返回到 ThumbnailScreen 上。Hero 小部件在渲染屏幕之间的无缝和迷人的过渡方面被证明是无价的,它对于增强电子商务应用程序的用户体验尤其有效。

隐式的动画

隐式动画是在 Flutter 中生成简单动画的重要工具,可响应小部件属性的变化。与深入研究复杂的动画控制器和微调器相比,隐式动画使您能够对小部件的属性制作动画,而无需关心动画的复杂细节。AnimatedContainer 小部件就是隐式动画工具的一个典型例子。

AnimatedContainer 小部件类似于标准的容器,但它拥有额外的动画功能,它可以动画地改变属性,如大小、颜色和形状,让我们通过一个示例来演示如何使用 AnimatedContainer 小部件在按钮被按下时动画地改变颜色。

隐式动画示例

// Import required packages and libraries
import 'package:flutter/material.dart';// Define the ImplicitAnimations widget
class ImplicitAnimations extends StatefulWidget {const ImplicitAnimations({Key? key}) : super(key: key);createState() => ImplicitAnimationsState();
}
class ImplicitAnimationsState extends State<ImplicitAnimations> {bool _isPressed = false;void _togglePressed() {setState(() {_isPressed = !_isPressed;});}Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: const Text('Color and Position Change'),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [AnimatedContainer(duration: const Duration(seconds: 1),height: 200.0,width: 200.0,margin: EdgeInsets.only(top: _isPressed ? 70.0 : 0.0,),decoration: BoxDecoration(color: _isPressed ? Colors.blue : Colors.red,borderRadius: BorderRadius.circular(_isPressed ? 50.0 : 0.0),),),const SizedBox(height: 20.0),ElevatedButton(onPressed: _togglePressed,child: const Text('ANIMATE'),),],),),),);}
}

在本例中,ImplicitAnimations 部件包含一个 _isPressed 布尔变量和一个 _togglePressed() 函数,用于切换布尔变量的值。该部件的状态类在 _togglePressed() 中调用了 setState(),以便在值发生变化时触发部件树的重建。

这个小部件的结构围绕着一个位于 Scaffold 中的 Center 小部件,这个 Center 小部件容纳了一个 Column ,它包含两个主要元素:

  1. AnimatedContainer。该小部件根据 _isPressed 值为其属性设置动画。在此示例中,高度、宽度、边距、颜色和边框半径的更改均以动画形式呈现。
  2. ElevatedButton。该按钮按下时会激活动画,调用 _togglePressed() 函数来切换 _isPressed

隐式动画是一种用户友好的方法,可以将动画引入 Flutter 应用程序,而无需复杂的动画控制器和渐变。

动画矢量图形

Flutter 通过不同的工具支持矢量动画图形,这进一步体现了 Flutter 制作复杂动态动画的能力。基于矢量的图形在调整大小后仍能保持质量。Flutter 利用不同的工具来创建动画并将其导入应用程序。

Rive

Rive 提供了一种制作跨平台动画的方法,从移动到 Web。Rive 动画可以导出为 Rive 文件,可以通过 Rive 包集成到您的 Flutter 项目中。该包还提供了一个 Rive 小部件来展示应用程序中的 Rive 动画。

让我们深入研究在 Flutter 应用中实现 Rive 的过程:

// Import required packages and libraries
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';// Define the RiveAnimations widget
class RiveAnimations extends StatelessWidget {const RiveAnimations({Key? key}) : super(key: key);Widget build(BuildContext context) {return Scaffold(backgroundColor: Colors.grey,body: Center(child: Container(decoration: BoxDecoration(borderRadius: BorderRadius.circular(20),color: Colors.blue,),width: 300,height: 300,child: const RiveAnimation.asset('assets/ball.riv'),),),);}
}

要使用 Rive 在 Flutter 动画中加入动画矢量图形,请按照以下步骤操作:

  1. 使用 rive 网站创建动画并以适当的格式下载。
  2. 将 Rive 包导入到你的 Flutter 项目中。
  3. 利用 RiveAnimation.asset 小部件,提供 Rive 文件的路径。

动画可以使用 RiveAnimationController 类进行控制,允许您根据需要启动、停止和暂停动画。

上面的动画是用 rive 制作的,它演示了一个球被弹起和踢出,但它并没有描绘 rive 的所有属性。Rive 可以用来为你的动画设置不同的状态,这让你的动画更动态。你可以让动画对应用程序的状态做出反应,但你必须擅长动画,才能利用 rive 的这一方面。除了 Rive,你还可以探索其他工具,如 Lottie,将预先构建的动画集成到 Flutter 应用程序中。

Lottie 动画

Lottie 是一个流行的库,它允许你使用 Adobe After Effects 等动画工具生成的 JSON 文件在应用中渲染动画。Lottie 动画是基于矢量的,提供流畅和高质量的视觉体验。在 Flutter 中,您可以使用 Lottie 包集成 Lottie 动画,它提供了 Lottie.assetLottie.network 小部件。

下面是一个如何在 Flutter 中创建 Lottie 动画的示例:

// Import required packages and libraries
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';// Define the LottieAnimations widget
class LottieAnimations extends StatelessWidget {const LottieAnimations({Key? key});Widget build(BuildContext context) {return Scaffold(body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [const SizedBox(height: 50),SizedBox(height: 200,width: 200,child: LottieBuilder.asset('assets/shopping.json'),),const SizedBox(height: 50),const Text('add items to cart',style: TextStyle(fontSize: 30),),],),),);}
}

Lottie 动画轻松让您的应用程序栩栩如生。只需找到或创建 Lottie 格式 (JSON) 所需的动画,导入 Lottie 包,然后使用提供的小部件在 Flutter 应用程序中展示您的动画。

结论

动画在移动应用程序开发中发挥着关键作用,通过为应用程序注入活力和参与度来增强用户体验。本文深入探讨了 Flutter 的动画功能,从动画系统和基本类到基于物理的动画、自定义动画和使用 Hero 小部件的动画过渡等高级技术。我们还讨论了隐式动画以及使用 Rive 和 Lottie 等包集成动画矢量图形。

通过利用这些资源,你可以深入研究 Flutter 动画的世界,制作迷人的动态用户界面,使你的移动应用程序与众不同。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/250301.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【自然语言处理】P2 PyTorch 基础 - 张量

目录 安装 PyTorch张量创建张量操作张量索引、切片、联合操作 CUDA张量 本系列博文我们将使用 PyTorch 来实现深度学习模型等。PyTorch 是一个开源的、社区驱动的深度学习框架。拥有强大的工具和库生态系统&#xff0c;包含 TorchVision&#xff08;用于图像处理&#xff09;、…

Android Studio非UI线程修改控件——定时器软件

目录 一、UI界面设计 1、UI样式 2、XML代码 二、功能编写 1、定义 2、实现方法 3、功能实现 一、UI界面设计 1、UI样式 2、XML代码 <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android…

Redmine项目管理工具的常见替代方案:从功能到优劣势的全方位分析

RedMine是一个非常受欢迎的项目管理工具&#xff0c;但它并不是万能的。随着时间的推移&#xff0c;许多功能和特性可能会发生变化或被取消。 因此&#xff0c;有许多其他工具可以成为RedMine的替代品。以下是六种可能的选择&#xff1a; 1、Zoho Projects&#xff1a; Zoho Pr…

CSC联合培养博士申请亲历|联系外导的详细过程

在CSC申报的各环节中&#xff0c;联系外导获得邀请函是关键步骤。这位联培博士同学的这篇文章&#xff0c;非常详细且真实地记录了申请过程、心理感受&#xff0c;并提出有益的建议&#xff0c;小编特推荐给大家参考。 2024年国家留学基金委公派留学项目即将开始&#xff0c;其…

【C/C++ 11】贪吃蛇游戏

一、题目 贪吃蛇游戏机制是通过控制蛇上下左右移动并吃到食物得分。 蛇头碰到墙壁或者碰到蛇身就游戏结束。 食物随机生成&#xff0c;蛇吃到食物之后蛇身变长&#xff0c;蛇速加快。 二、算法 1. 初始化游戏地图并打印&#xff0c;地图的边缘是墙&#xff0c;地图的每个坐…

JMeter GUI:测试计划和工作台

什么是测试计划&#xff1f; 测试计划是您添加 JMeter 测试所需元素的地方。 它存储运行所需测试所需的所有元素&#xff08;如线程组、计时器等&#xff09;及其相应的设置。 下图显示了测试计划的示例 测试计划是您添加 JMeter 测试所需元素的地方。 它存储运行所需测试…

Flutter 仿抖音 TikTok 上下滑动 播放视频

Flutter 仿抖音 TikTok 上下滑动 播放视频UI框架&#xff0c;视频播放使用 video_player github&#xff1a;GitHub - PangHaHa12138/TiktokVideo: Flutter 仿抖音 TikTok 上下滑动 播放视频UI框架 实现功能&#xff1a; 1.上下滑动自动播放切换视频&#xff0c;loading 封面…

k8s kubeadm部署安装详解

目录 kubeadm部署流程简述 环境准备 步骤简述 关闭 防火墙规则、selinux、swap交换 修改主机名 配置节点之间的主机名解析 调整内核参数 所有节点安装docker 安装依赖组件 配置Docker 所有节点安装kubeadm&#xff0c;kubelet和kubectl 定义kubernetes源并指定版本…

网络异常案例四_IP异常

问题现象 终端设备离线&#xff0c;现场根据设备ip&#xff0c;ping不通。查看路由器。 同一个路由器显示的终端设备&#xff08;走同一个wifi模块接入&#xff09;&#xff0c;包含不同网段的ip。 现场是基于三层的无线漫游&#xff0c;多个路由器wifi配置了相同的ssid信息&a…

某赛通电子文档安全管理系统 UploadFileToCatalog SQL注入漏洞复现

0x01 产品简介 某赛通电子文档安全管理系统(简称:CDG)是一款电子文档安全加密软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产,对电子文档进行全生命周期防护,系统具有透明加密、主动加密、智能…

【机器学习】AAAI 会议论文聚类分析

实验五&#xff1a;AAAI 会议论文聚类分析 ​ 本次实验以AAAI 2014会议论文数据为基础&#xff0c;要求实现或调用无监督聚类算法&#xff0c;了解聚类方法。 1 任务介绍 ​ 每年国际上召开的大大小小学术会议不计其数&#xff0c;发表了非常多的论文。在计算机领域的一些大…

【二进制漏洞】缓冲区溢出漏洞

天命&#xff1a;好像复现成功了&#xff0c;又好像没有完全成功 学习视频&#xff1a;抓住漏洞&#xff01;缓冲区溢出漏洞利用实例&#xff0c;如何利用溢出执行Shell Code_哔哩哔哩_bilibili 漏洞复现 实验环境&#xff1a;kali &#xff08;其实啥都试过&#xff0c;windo…

Linux基础知识合集

整理了一下学习的一些关于Linux的一些基础知识&#xff0c;同学们也可以通过公众号菜单栏查看&#xff01; 一、基础知识 Linux基础知识 Linux命令行基础学习 Linux用户与组概念初识 Linux文件与目录权限基础 Linux中文件内容的查看 Linux系统之计划任务管理 二、服务器管理 Vm…

通过与chatGPT交流实现零样本事件抽取

1、写作动机&#xff1a; 近来的大规模语言模型&#xff08;例如Chat GPT&#xff09;在零样本设置下取得了很好的表现&#xff0c;这启发作者探索基于提示的方法来解决零样本IE任务。 2、主要贡献&#xff1a; 提出了基于chatgpt的多阶段的信息抽取方法&#xff1a;在第一阶…

DHCP简介

定义 动态主机配置协议DHCP&#xff08;Dynamic Host Configuration Protocol&#xff09;是一种用于集中对用户IP地址进行动态管理和配置的技术。即使规模较小的网络&#xff0c;通过DHCP也可以使后续增加网络设备变得简单快捷。 DHCP是在BOOTP&#xff08;BOOTstrap Protoc…

[GN] 设计模式—— 创建型模式

文章目录 创建型模式单例模式 -- 确保对象唯一性例子优化饿汉式懒汉式 优缺点使用场景 简单工厂模式例子&#xff1a;优化优缺点适用场景 工厂方法模式 -- 多态工厂的实现例子优缺点优化适用场景 抽象工厂模式 -- 产品族的创建例子优缺点适用场景 总结 创建型模式 单例模式 –…

公共用例库计划--个人版(六)典型Bug页面设计与开发

1、任务概述 本次计划的核心任务是开发一个&#xff0c;个人版的公共用例库&#xff0c;旨在将各系统和各类测试场景下的通用、基础以及关键功能的测试用例进行系统性地归纳整理&#xff0c;并以提高用例的复用率为目标&#xff0c;力求最大限度地减少重复劳动&#xff0c;提升…

接口安全测试

一、后台接口分类 1、接口类别&#xff1a;restful(json) soap(xml) 2、协议 &#xff1a;http https(ssl) 3、restful接口请求类型 get操作是安全的 post的操作是不安全的 同put delete也是不安全的 4、现状和问题 大部分APP的接口都采用restful架构&#xff0c;restful…

G7-Semi-Supervised GAN解读

本文为&#x1f517;365天深度学习训练营 中的学习记录博客 原作者&#xff1a;K同学啊|接辅导、项目定制 我的环境&#xff1a; 1.语言&#xff1a;python3.7 2.编译器&#xff1a;pycharm 3.深度学习框架Pytorch 1.8.0cu111 论文地址 一、理论理解 半监督生成对抗网络&…

C语言系列-联合

&#x1f308;个人主页: 会编程的果子君 ​&#x1f4ab;个人格言:“成为自己未来的主人~” 目录 联合体 联合体类型的声明 联合体的特点 相同成员的结构体和联合体对比 联合体大小的计算 联合的一个练习 联合体 联合体类型的声明 像结构体一样&#xff0c;联合体也是由…