Flutter实现动画列表AnimateListView

由于业务需要,在打开列表时,列表项需要一个从右边飞入的动画效果,故封装一个专门可以执行动画的列表组件,可以自定义自己的动画,内置有水平滑动,缩放等简单动画。花里胡哨的动画效果由你自己来定制吧。

功能:

1.可自定义动画。

2.内置水平滑动和缩放动画。

演示:

代码:

import 'dart:math';import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';///可设置动画的列表。
///内部使用的是[SingleChildScrollView]实现,
///需要外层设置定义可约束高度。
class KqAnimateListView<T> extends StatefulWidget {///数据final List<T> data;///列表final Widget Function(T t) item;///动画自定义final IAnimate? animate;///是否需要每次刷新时都执行动画final bool isNeedFlashEveryTime;const KqAnimateListView({super.key,required this.item,required this.data,this.animate,this.isNeedFlashEveryTime = false,});@overrideState<StatefulWidget> createState() => _KqAnimateListViewState<T>();
}class _KqAnimateListViewState<T> extends State<KqAnimateListView<T>>with TickerProviderStateMixin {late IAnimate animate;late AnimationController controller;late Animation animation;@overridevoid initState() {super.initState();animate = widget.animate ?? ScaleAnimate();animate.init(widget.data.length);controller = animate.getAnimationController(this);animation = animate.getAnimation(controller, this);//启动动画(正向执行)controller.forward();}@overridevoid didUpdateWidget(covariant KqAnimateListView<T> oldWidget) {super.didUpdateWidget(oldWidget);if (widget.isNeedFlashEveryTime) {animate = widget.animate ?? ScaleAnimate();animate.init(widget.data.length);controller = animate.getAnimationController(this);animation = animate.getAnimation(controller, this);//启动动画(正向执行)controller.forward();}}@overrideWidget build(BuildContext context) {return SizedBox.expand(child: SingleChildScrollView(child: Column(children: _getChildren(context),),),);}List<Widget> _getChildren(BuildContext context) {List<Widget> list = [];for (int i = 0; i < widget.data.length; i++) {Widget child = widget.item.call(widget.data[i]);list.add(animate.animate(context, i, child, animation, controller),);}return list;}@overridevoid dispose() {controller.dispose();super.dispose();}
}///动画抽象类。
///实现该类,定制自己的列表动画。
abstract class IAnimate {///初始化///[length] 列表长度void init(int length);///获取AnimationControllerAnimationController getAnimationController(TickerProvider provider);///获取AnimationAnimation getAnimation(AnimationController controller, State<StatefulWidget> state);///定制自己的动画,每一个item都会调用到animate,///当需要差异动画时需要根据[index]计算不同item的动画时机///[widget] 执行动画之后的widget///[index] 列表的item的indexWidget animate(BuildContext context,int index,Widget widget,Animation animation,AnimationController controller,);
}///水平移动动画
class HorizontalAnimate extends IAnimate {///动画执行时长比例static double rate = 0.4;///单个动画执行长度static double baseGap = 1000.0;///两个个动画执行间隔长度static double twoGap = 200.0;///动画执行的总长度,根据列表长度动态计算值late double gap;///动画是从左边还是右边开始执行HorizontalAnimateDirection direction;HorizontalAnimate({this.direction = HorizontalAnimateDirection.right});@overridevoid init(int length) {gap = length * twoGap + baseGap;}@overrideWidget animate(BuildContext context, int index, Widget widget,Animation animation, AnimationController controller) {double width = context.width;///范围0->1double mix = (animation.value - twoGap * index) / baseGap;if (mix > 1) {mix = 1;}double left = width * (1 - mix);return Container(transform: Matrix4.translationValues(direction == HorizontalAnimateDirection.left ? -left : left, 0, 0),child: widget,);}@overrideAnimationController getAnimationController(TickerProvider provider) {return AnimationController(duration: Duration(milliseconds: (gap * rate).toInt()),vsync: provider);}@overrideAnimation getAnimation(AnimationController controller, State<StatefulWidget> state) {return Tween(begin: 0.0, end: gap).animate(controller)..addListener(() {if (state.mounted) {state.setState(() {});}});}
}enum HorizontalAnimateDirection {///左边left,///右边right;
}///缩放动画
class ScaleAnimate extends IAnimate {///动画执行时长比例static double rate = 0.4;///单个动画执行长度static double baseGap = 1000.0;///两个个动画执行间隔长度static double twoGap = 200.0;///动画执行的总长度,根据列表长度动态计算值late double gap;@overrideWidget animate(BuildContext context, int index, Widget widget,Animation animation, AnimationController controller) {double width = context.width;///范围0.5->1double mix = ((animation.value - twoGap * index) / baseGap + 1) / 2;if (mix > 1) {mix = 1;}double widthMix = width * mix;return SizedBox(width: max(0, widthMix),child: widget,);}@overrideAnimationController getAnimationController(TickerProvider provider) {return AnimationController(duration: Duration(milliseconds: (gap * rate).toInt()),vsync: provider);}@overrideAnimation getAnimation(AnimationController controller, State<StatefulWidget> state) {return Tween(begin: 0.0, end: gap).animate(controller)..addListener(() {if (state.mounted) {state.setState(() {});}});}@overridevoid init(int length) {gap = length * twoGap + baseGap;}
}

 使用:

                KqAnimateListView(data: const ["Test1","Test2","Test3","Test3","Test3","Test3","Test3","Test3","Test3","Test3","Test3","Test3","Test3"],item: (t) {return Container(width: double.infinity,height: 50,color: Colors.redAccent,margin: EdgeInsets.only(top: 10.r),child: Text(t),);},animate: type == 0? HorizontalAnimate(direction: HorizontalAnimateDirection.left): type == 1? HorizontalAnimate(direction: HorizontalAnimateDirection.right): ScaleAnimate(),isNeedFlashEveryTime: true,)

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

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

相关文章

StableVideo:使用Stable Diffusion生成连续无闪烁的视频

使用Stable Diffusion生成视频一直是人们的研究目标&#xff0c;但是我们遇到的最大问题是视频帧和帧之间的闪烁&#xff0c;但是最新的论文则着力解决这个问题。 本文总结了Chai等人的论文《StableVideo: Text-driven consistency -aware Diffusion Video Editing》&#xff…

学习Linux的注意事项(使用经验;目录作用;服务器注意事项)

本篇分享学习Linux过程中的一些经验 文章目录 1. Linux系统的使用经验2. Linux各目录的作用3. 服务器注意事项 1. Linux系统的使用经验 Linux严格区分大小写Linux中所有内容以文件形式保存&#xff0c;包括硬件&#xff0c;Linux是以管理文件的方式操作硬件 硬盘文件是/dev/s…

2023-08-23 LeetCode每日一题(统计点对的数目)

2023-08-23每日一题 一、题目编号 1782. 统计点对的数目二、题目链接 点击跳转到题目位置 三、题目描述 给你一个无向图&#xff0c;无向图由整数 n &#xff0c;表示图中节点的数目&#xff0c;和 edges 组成&#xff0c;其中 edges[i] [ui, vi] 表示 ui 和 vi 之间有一…

Linux(实操篇二)

Linux实操篇 Linux(实操篇二)1. 常用基本命令1.3 时间日期类1.3.1 date显示当前时间1.3.2 显示非当前时间1.3.3 date设置系统时间1.3.4 cal查看日历 1.4 用户管理命令1.4.1 useradd添加新用户1.4.2 passwd设置用户密码1.4.3 id查看用户是否存在1.4.4 cat /etc/passwd 查看创建了…

用香港服务器域名需要备案吗?

​  在选择服务器的时候&#xff0c;很多人会考虑使用香港服务器。香港服务器的一个优势就是不需要备案。不管是虚拟主机还是云主机&#xff0c;无论是个人网站还是商业网站&#xff0c;都不需要进行备案手续。 域名实名认证 虽然不需要备案&#xff0c;但使用香港服务器搭建…

基于Linux操作系统的keepalived双机热备和keepalived+lvs(DR)基本配置操作

目录 keepalived双机热备 一、概述 &#xff08;一&#xff09;具体工作原理如下&#xff1a; &#xff08;二&#xff09;实验拓补 二、安装NFS、配置 1、第一台机器配置&#xff1a;NFS &#xff1a;192.168.11.101 2、更改配置文件 3、安装NFS进行目录共享 4、编辑…

Linux 之 yum使用(yum 命令使用讲解)

yum使用 1.yum安装软件 yum -y install vim [rootlocalhost ~]# yum -y install vim 已加载插件&#xff1a;fastestmirror Bad id for repo: mirrors.aliyun.com_docker-ce_linux_centos_docker-ce.xn--repo()-mu8ig98h4l0hokj, byte ( 60 Loading mirror speeds from cac…

无涯教程-机器学习 - 矩阵图函数

相关性是有关两个变量之间变化的指示&#xff0c;在前面的章节中&#xff0c;无涯教程讨论了Pearson的相关系数以及相关的重要性&#xff0c;可以绘制相关矩阵以显示哪个变量相对于另一个变量具有较高或较低的相关性。 在以下示例中&#xff0c;Python脚本将为Pima印度糖尿病数…

jemter连接数据json断言

文章目录 一、jmeter连接数据库1、加载JDBC驱动2、连接数据3、SQL Query的Query Type使用方法&#xff1a;4、Variable Name使用方法&#xff1a;5、Result variable name使用方法&#xff1a; 二、Json响应断言1、添加 》 断言 》 JSON断言2、JSON断言界面参数说明&#xff1a…

【100天精通python】Day46:python网络编程基础与入门

目录 专栏导读 1 网络编程的基础 2. 基本概念和协议 2.1 计算机网络基础 2.2 网络协议、IP地址、端口号 2.3 常见网络协议 3. 套接字编程 3.1 套接字的基本概念 3.2 套接字的基本操作 3.3 套接字通信模型和方法&#xff1a;send、recv 3.3.1 TCP通信模型 3.3.2 U…

VScode 编辑器报错: ‘HelloWorld‘ is declared but its value is never read.

.vue文件被标识红色波浪线&#xff1b;提示&#xff1a; HelloWorld is declared but its value is never read. 问题原因&#xff1a; 因为vue3已经不支持vetur插件。 1、在扩展里面进行搜索Vetur插件&#xff0c;进行禁用或卸载&#xff1b; 2、在 VScode扩展里面搜索并下载…

DDR PHY

1.ddr phy架构 1.pub&#xff08;phy unility block&#xff09; 支持特性&#xff1a; &#xff08;1&#xff09;不支持SDRAM的DLL off mode &#xff08;2&#xff09;数据位宽是以8bit逐渐递增的&#xff08;这样做的目的是因为可能支持16/32/64bit的总线位宽&#xff…

Android学习之路(11) ActionBar与ToolBar的使用

自android5.0开始&#xff0c;AppCompatActivity代替ActionBarActivity&#xff0c;而且ToolBar也代替了ActionBar&#xff0c;下面就是ActionBar和ToolBar的使用 ActionBar 1、截图 2、使用 2.1、AppCompatActivity和其对应的Theme AppCompatActivity使用的是v7的ActionBa…

【stable-diffusion使用扩展+插件和模型资源(下)】

插件模型魔法图片等资源&#xff1a;https://tianfeng.space/1240.html 书接上文&#xff1a;&#xff08;上&#xff09; 插件推荐 1.lobe theme lobe theme是一款主题插件&#xff0c;直接可以在扩展安装 界面进行了重新布局&#xff0c;做了一些优化&#xff0c;有兴趣的…

Unity报错DllNotFoundException:sqlite3

Unity项目中要使用轻型数据库sqlite&#xff0c;除了导入sqlite3.dll外&#xff0c;还需要导入Mono.Data.Sqlite.dll和System.Data.dll&#xff08;工程里或者编辑器里面有System.Data.dll时就不需要&#xff09;两个文件。 如果在编辑器中运行出现 “DllNotFoundException:sql…

Vue2(状态管理Vuex)

目录 一&#xff0c;状态管理Vuex二&#xff0c;state状态三&#xff0c;mutations四&#xff0c;actions五&#xff0c;modules最后 一&#xff0c;状态管理Vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并…

聚观早报 | 云鲸扫拖机器人J4体验;芯科科技第三代无线开发平台

【聚观365】8月24日消息 云鲸扫拖机器人J4体验 芯科科技推出第三代无线开发平台 英伟达与VMWare宣布扩大合作 万物新生&#xff08;爱回收&#xff09;2023年二季度财报 充电桩需求增长带动汽车后服务市场 云鲸扫拖机器人J4体验 家庭卫生清洁是每个人都无法回避的事情&am…

C++实现客户端/服务端通信(一)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 C实现客户端/服务端通信&#xff08;一&#xff09; 网络编程的基本概念1. 客户端/服务器通信模型&#xff1a;2. socket函数&#xff1a;3. 主机字节序和网络字节序&#xf…

运放的分类、运放的参数

一、运放的分类 运放按功能分为通用运放与专用运放&#xff08;高速运放、精密运放、低IB运放等&#xff09;。 1.1通用运放 除廉价外&#xff0c;没有任何最优指标的运放。 例&#xff1a;uA741&#xff0c;LM324&#xff0c;TL06X&#xff0c;TL07X、TL08X等 国外知名运放…

小红书口碑营销技巧有哪些,打造独特品牌内容

作为一款社交电商平台&#xff0c;从目前来看&#xff0c;其实小红书也算是比较不错的口碑营销传播平台了。今天就来带大家一起分享下&#xff0c;小红书口碑营销技巧有哪些&#xff0c;打造独特品牌内容&#xff01; ​ 一、小红书口碑营销怎么做 1. 了解目标用户 首先需要明…