Compose 动画 (八) : Compose中的动画差值器 AnimationSpec

1. AnimationSpec是什么

Android Compose中的AnimationSpec用来自定义动画规格。
啥意思呢,其实就是类似于传统View体系中的差值器Interpolator,但是比起差值器,又提供了更多的功能。
根据其不同的子类,可以来控制动画执行时长、设置动画执行多少时间到动画的某个位置、实现仿弹簧的动画效果、指定动画执行次数等等功能。

val alpha: Float by animateFloatAsState(
    targetValue = if (enabled) 1f else 0.5f,
    animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing) //这里的tween就是个AnimationSpec
)

先来看下Compose中所有的AnimationSpec

在这里插入图片描述
看上去很多是不是,但实际上我们只需要记住这几个重点的就行
在这里插入图片描述

其中,蓝色背景的是可以直接进行使用的 (实现类),灰色背景的是接口,AnimationSpec也是一个接口。

interface AnimationSpec<T> {
    fun <V : AnimationVector> vectorize(
        converter: TwoWayConverter<T, V>
    ): VectorizedAnimationSpec<V>
}

1. SpringSpec

SpringSpec实现了AnimationSpec接口,提供了一些列基于弹簧的物理动画效果。
很多动画内部AnimationSpec使用的默认值都是spring,比如animateXXXAsState以及updateTransition等。
因为spring的动画效果基于物理原理,使动画更真实自然。
同时,因为spring是基于物理规律的,所以无法指定动画执行时长,而是会基于物理规律来确定动画执行时长。

class SpringSpec<T>(
    val dampingRatio: Float = Spring.DampingRatioNoBouncy,
    val stiffness: Float = Spring.StiffnessMedium,
    val visibilityThreshold: T? = null
) : FiniteAnimationSpec<T>

spring有三个传参,dampingRatiostiffnessvisibilityThreshold,前两个参数主要用来控制弹跳动画的动画效果。

1.1 使用示例

var change by remember {
    mutableStateOf(false)
}
val offsetX = remember(change) {
    if (change) 350.dp else 50.dp
}
val offsetXAnim = remember {
    Animatable(offsetX, Dp.VectorConverter)
}
LaunchedEffect(key1 = change, block = {
    offsetXAnim.animateTo(
        offsetX, spring(Spring.DampingRatioMediumBouncy, stiffness = Spring.StiffnessMedium)
    )
})

Box(modifier = Modifier
    .padding(offsetXAnim.value, 0.dp, 0.dp, 0.dp)
    .size(100.dp)
    .background(Color.Blue)
    .clickable { change = !change })

效果如下所示
在这里插入图片描述

1.2 dampingRatio

dampingRation表示弹簧的阻尼比。这个值越大,阻尼越大。
不同的dampingRatio有不同的效果,如下图所示
在这里插入图片描述

如果不额外指定,默认会使用DampingRationNoBouncy,是不带弹簧效果的。

需要注意dampingRation不能小于0

1.3 stiffness

stiffness定义弹簧的刚度值,弹簧有多想变回去,这个值越大,回弹的越快。
Composestiffness定义的常量如下,默认值是StiffnessMedium

const val StiffnessHigh = 10_000f
const val StiffnessMedium = 1500f
const val StiffnessMediumLow = 400f
const val StiffnessLow = 200f
const val StiffnessVeryLow = 50f

需要注意stiffness必须大于0

1.4 visibilityThreshold

visibilityThreshold用来指定一个阈值,当动画到达这个阈值时,动画会立即停止。

2. TweenSpec

这里的Tween不是老的View体系动画中的补间动画,而是和Interpolator(差值器)是一个作用的东西。
tween动画必须在规定时间内完成,它不能像SpringSpec那样完全基于物理规律进行动画,

class TweenSpec<T>(
    val durationMillis: Int = DefaultDurationMillis,
    val delay: Int = 0,
    val easing: Easing = FastOutSlowInEasing
)

tween有3个参数

  • durationMillis : 动画执行时间 (ms)
  • delayMillis : 延迟多久开始执行
  • Easing : 衰减曲线动画效果,用来配置怎么进行渐变的

2.1 使用示例

var change by remember {
    mutableStateOf(false)
}
val offsetX = remember(change) {
    if (change) 300.dp else 0.dp
}
val offsetXAnim = remember {
    Animatable(offsetX, Dp.VectorConverter)
}
LaunchedEffect(key1 = change, block = {
    //offsetXAnim.animateTo(offsetX, TweenSpec(easing = LinearEasing))
    //tween是TweenSpec的简便写法,这两种都是可以用的
    offsetXAnim.animateTo(
        offsetX, tween(durationMillis = 1000, delayMillis = 0, easing = FastOutSlowInEasing)
    )
})

Box(modifier = Modifier
    .padding(offsetXAnim.value, 0.dp, 0.dp, 0.dp)
    .size(100.dp)
    .background(Color.Blue)
    .clickable { change = !change })

效果如下所示

在这里插入图片描述

2.2 Easing

Compose中预置的Easing 有这些

//先加速后减速(默认),相当于差值器中的AccelerateDecelerateInterpolator
val FastOutSlowInEasing: Easing = CubicBezierEasing(0.4f, 0.0f, 0.2f, 1.0f)
//入场速度快,慢慢减速到0,相当于差值器中的DecelerateInterpolator
val LinearOutSlowInEasing: Easing = CubicBezierEasing(0.0f, 0.0f, 0.2f, 1.0f)
//从0慢慢加速到很快,相当于差值器中的AccelerateInterpolator
val FastOutLinearInEasing: Easing = CubicBezierEasing(0.4f, 0.0f, 1.0f, 1.0f)
//线性
val LinearEasing: Easing = Easing { fraction -> fraction }

2.1.1 LinearEasing

LaunchedEffect(key1 = big, block = {
    anim.animateTo(size, TweenSpec(easing = LinearEasing))
})

2.3 自定义Easing

使用CubicBezierEasing可以自定义Easing
使用贝塞尔曲线API网站 : cubic-bezier.com ,专门用来展现三阶贝塞尔曲线的效果的,可以查到对应三阶贝塞尔曲线具体的参数,我们传入到CubicBezierEasing中就可以自定义Easing了。

比如这里

  • FastOutSlowInEasing对应的参数是CubicBezierEasing(0.4f, 0.0f, 0.2f, 1.0f)
  • LinearOutSlowInEasing对应的参数是CubicBezierEasing(0.0f, 0.0f, 0.2f, 1.0f)
    在这里插入图片描述

3. SnapSpec

即时生效动画规格,和anim.snapTo的效果是一样的

anim.snapTo()
anim.animateTo(offset,SnapSpec(delayMillis=100/*可以设置延迟*/))
anim.animateTo(offset,snap(delayMillis=100/*可以设置延迟*/))

3.1 使用示例

var change by remember {
    mutableStateOf(false)
}
val offsetX = remember(change) {
    if (change) 300.dp else 0.dp
}
val offsetXAnim = remember {
    Animatable(offsetX, Dp.VectorConverter)
}
LaunchedEffect(key1 = change, block = {
    offsetXAnim.animateTo(
        offsetX, snap(delayMillis = 100)
    )
})

Box(modifier = Modifier
    .padding(offsetXAnim.value, 0.dp, 0.dp, 0.dp)
    .size(100.dp)
    .background(Color.Blue)
    .clickable { change = !change })

效果如下所示
在这里插入图片描述

4. KeyframesSpec

关键帧动画规格,相当于可以分段的tweenSpec,但是动画的复用性会降低

anim.animateTo(size,keyframes{
	//infix function 中缀函数
	250.dp at 0 with LinearEasing //作用于 0毫秒-150毫秒
	500.dp at 150 with FastOutSlowInEasing//作用于150毫秒及之后  //默认是LinearEasing
	durationMillis = 450 //执行时长
	delayMillis = 50 //延迟多久执行
})

1.until(100) ----> 1 until 100 // 这也是一个中缀函数

4.1 使用示例

var change by remember {
    mutableStateOf(false)
}
val offsetX = remember(change) {
    if (change) 300.dp else 0.dp
}
val offsetXAnim = remember {
    Animatable(offsetX, Dp.VectorConverter)
}
LaunchedEffect(key1 = change, block = {
    offsetXAnim.animateTo(offsetX, keyframes {
        80.dp at 250 with FastOutSlowInEasing //0至150毫秒
        durationMillis = 1000 //动画持续多久
        delayMillis = 50 //延迟多久执行
    })
})

Box(modifier = Modifier
    .padding(offsetXAnim.value, 0.dp, 0.dp, 0.dp)
    .size(100.dp)
    .background(Color.Blue)
    .clickable { change = !change })

显示效果

在这里插入图片描述

5. RepeatableSpec

循环动画规格,SpringSpec不能放进RepeatableSpec里面,必须是DurationBasedAnimationSpec的子类,SpringSpec属于物理弹簧效果,真实环境下肯定是无法持续循环的。

fun <T> repeatable(
    iterations: Int, //重复次数
    animation: DurationBasedAnimationSpec<T>, 
    repeatMode: RepeatMode = RepeatMode.Restart, //重复模式 : 重新开始 / 翻转
    initialStartOffset: StartOffset = StartOffset(0) //初始偏移(时间偏移)
)

5.1 使用示例

var change by remember {
    mutableStateOf(false)
}
val offsetX = remember(change) {
    if (change) 300.dp else 0.dp
}
val offsetXAnim = remember {
    Animatable(offsetX, Dp.VectorConverter)
}
LaunchedEffect(key1 = change, block = {
    RepeatMode.Restart
    offsetXAnim.animateTo(offsetX, repeatable(3,tween(),RepeatMode.Reverse))
})

Box(modifier = Modifier
    .padding(offsetXAnim.value, 0.dp, 0.dp, 0.dp)
    .size(100.dp)
    .background(Color.Blue)
    .clickable { change = !change })

效果如下所示

在这里插入图片描述

6. InfiniteRepeatableSpec

InfiniteRepeatableSpec是无限动画规格,会无限执行。
RepeatableSpec本质上没有区别,只有一个区别,无限和有限。

anim.animateTo(size, infiniteRepeatable(tween(),RepeatMode.Reverse))

效果如下所示

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

运维1.12了解集中式日志管理工具 ELK 的基本用法,包括数据采集、搜索和展示

ELK 是一个由三个开源项目组成的日志管理工具&#xff0c;它们分别是 Elasticsearch、Logstash 和 Kibana。Elasticsearch 是一个基于 Lucene 的搜索引擎&#xff0c;它可以提供实时的分布式搜索和分析能力&#xff1b;Logstash 是一个日志收集和处理工具&#xff0c;可以实现多…

《白帽子讲Web安全》世界观安全

1.Web安全简史1.1中国黑客简史对于现代计算机系统来说&#xff0c;在用户态的最高权限是root&#xff0c;也是黑客们最渴望能够获取的系统最高权限。不想拿到“root”的黑客&#xff0c;不是好黑客。在现实世界中&#xff0c;真正造成破坏的&#xff0c;往往并非那些挖掘并研究…

10秒去除WPS Office弹窗广告教程(2023.3.31最新)

目录 前言 步骤 1. 右击WPS Office&#xff0c;打开文件所在目录 2. 打开第二个文件夹 3. 进入office 6文件夹 4. 找到文件ksomisc.exe 5. 右击选择以管理员身份运行 6. 打开后是下面的界面&#xff0c;点击“高级(A)...” 7. 按照下图操作 8. 最后点击退出就设置完…

Mybatis配置之属性优化理解【transactionManager、dataSource、properties】

文章目录一.Mybatis配置之属性优化1.1 配置解析1.2 默认配置环境1.2.1 事务管理器&#xff08;transactionManager&#xff09;了解即可。1.2.2 数据源&#xff08;dataSource&#xff09;1.3 属性&#xff08;properties&#xff09;一.Mybatis配置之属性优化 1.1 配置解析 …

PyTorch 深度学习实战 |用 TensorFlow 训练神经网络

为了更好地理解神经网络如何解决现实世界中的问题&#xff0c;同时也为了熟悉 TensorFlow 的 API&#xff0c;本篇我们将会做一个有关如何训练神经网络的练习&#xff0c;并以此为例&#xff0c;训练一个类似的神经网络。我们即将看到的神经网络&#xff0c;是一个预训练好的用…

达梦回滚表空间的空间占用和释放

我们知道DML和DDL的区别之一是DML&#xff08;INSERT、UPDATE、DELETE&#xff09;操作数据库会产生重做日志和回滚日志&#xff0c;DDL不会产生重做日志和回滚日志&#xff0c;本章从系统表和动态视图上来分析达梦数据库DML和DDL对回滚表空间的占用&#xff0c;以及达梦回滚表…

C++11:可变参数模板/lambda表达式

1.可变参数模板 C11的新特性可变参数模板能够让我们创建可以接受可变参数的函数模板和类模板&#xff0c;相比C98和C03&#xff0c;类模板和函数模板中只能含固定数量的模板参数&#xff0c;可变参数模板无疑是一个巨大的改进。可是可变参数模板比较抽象&#xff0c;因此这里只…

vue路由守卫死循环及路由守卫使用

当前业务要求&#xff1a; 通过判断本地sessionstorge判断当前是否需要登陆页面 问题场景&#xff1a;用户登陆进入页面内部&#xff0c;点击退出登录&#xff0c;清除本地用户信息&#xff0c;页面跳转至登陆页面&#xff0c;使用浏览器的回退可以正常返回至项目内部。需要改…

kettle开发篇-更新-Day38

目录 前言&#xff1a; 一、更新组件介绍 1.1界面 1.2废话介绍 1.3重点解释 二、应用案例 2.1转换效果 2.2转换简介 三、总结 前言&#xff1a; 前面我们通过oracle的索引来处理单表超1亿的数据量表的查询问题&#xff0c;通过针对主键&#xff0c;展示的维度做多套索引…

如何使用码匠连接 GaussDB

目录 在码匠中集成 GaussDB 在码匠中使用 GaussDB 关于码匠 GaussDB 是华为推出的一个高性能、高可靠、高安全的分布式数据库管理系统。它采用多活架构&#xff0c;支持全球数据同步&#xff0c;可实现数据的实时同步和容灾备份&#xff0c;可满足不同业务场景下的数据管理…

《钢琴调律原理及应用》 笔记

【第一章 绪论】第一节 钢琴调律的概念 美国人威廉布雷德怀特于 1917 年发表了世界上第一部关于钢琴调律理论与技术的著作&#xff0c;书名为《钢琴调律与相关技术》 福岛琢郎于1950年发表一部名为《钢琴的构造调律修理》的专著 80年代初&#xff0c;在沈阳音院任教的张琨先生…

蓝桥杯正确的解题姿势

在做算法题的过程中最忌讳的就是上来就一顿乱敲&#xff0c;一开始我就是这样&#xff0c;但随着不断的刷题和老师的指导&#xff0c;总结了自己的刷题方法 示例题目 三角回文数 问题描述 对于正整数 n, 如果存在正整数 k使得 n123...kk(k1)/2 , 则 n 称为三角数。例如, 66066 …

弱监督实例分割 Box-supervised Instance Segmentation with Level Set Evolution 论文笔记

弱监督实例分割 Box-supervised Instance Segmentation with Level Set Evolution 论文笔记一、Abstract二、引言三、相关工作3.1 基于 Box 的实例分割3.2 基于层级的分割四、提出的方法4.1 图像分割中的层级模型4.2 基于 Box 的实例分割在 Bounding Box 内的层级进化输入的数据…

CentOS7+LAMP+DVWA靶机搭建

一、什么是DVWA Damn Vulnerable Web Application (DVWA)(译注&#xff1a;可以直译为&#xff1a;"该死的"不安全Web应用程序)&#xff0c;是一个编码差的、易受攻击的 PHP/MySQL Web应用程序。 它的主要目的是帮助信息安全专业人员在合法的环境中&#xff0c;练习…

【自动化】selenium配置步骤 | 备份本地资源

1、安装jdk 2、设置环境变量 .1、CLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar .2、JAVA_HOME C:\Program Files\Java\jdk1.8.0_231 .3、PATH 新增 %JAVA_HOME%\bin 3、安装chrome 版本&#xff1a;85.0.4183.83 4、禁用chrom…

AOP配置管理

AOP配置管理4&#xff0c;AOP配置管理4.1 AOP切入点表达式4.1.1 语法格式4.1.2 通配符4.1.3 书写技巧4.2 AOP通知类型4.2.1 类型介绍4.2.2 环境准备4.2.3 通知类型的使用前置通知后置通知环绕通知基本使用注意事项返回后通知异常后通知通知类型总结知识点1&#xff1a;After知识…

基于SpringBoot+SpringCloud+Vue前后端分离项目实战 --开篇

本文目录前言做项目的三大好处强强联手(天狗组合)专栏作者简介专栏的优势后端规划1. SpringBoot 和 SpringCloud 的选择2. Mybatis 和 MybatisPlus 和 JPA 的选择3. MySQL 和 Mongodb 的选择4. Redis 和 RocketMQ5. 后端规划小总结后端大纲提前掌握的知识点一期SpringBoot二期S…

经典文献阅读之--LOCUS 2.0(LiDAR为中心的多传感器LSLAM)

0. 简介 在20年DARPA地下挑战赛中CoSTAR队伍提出了LOCUS这个深度学习模块&#xff0c;在两年后LOCUS2.0出世&#xff0c;LOCUS 2.0包括一种新的基于法线的广义迭代最近点&#xff08;GICP&#xff09;公式&#xff0c;该公式减少了点云对齐的计算时间&#xff0c;一种自适应体…

PowerTCP Sockets for .NET 6.1.5 Crack

PowerTCP Sockets for .NET PowerTCP Sockets for .NET 包含易于使用的 TCP 和 UDP 组件&#xff0c;可帮助您创建 Internet 客户端应用程序&#xff0c;只需几行代码和方便的事件。Ping 组件使用 ICMP、UDP 和 TCP 启用服务器验证&#xff0c;而跟踪组件执行异步跟踪路由以实…

三、数据链路层

&#xff08;一&#xff09;纠错与检错1、奇偶校验码&#xff08;再研究下&#xff0c;原理知道&#xff0c;具体过程无法重现&#xff09;分为奇校验和偶校验&#xff0c;奇偶校验位在首部或尾部&#xff0c;奇偶校验满信息位奇偶校验位&#xff08;1&#xff09;原理&#xf…