手把手教你写 Compose 动画 -- 流程定制型动画 API:Animatable()

2023-12-07 16:45

本文主要是介绍手把手教你写 Compose 动画 -- 流程定制型动画 API:Animatable(),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

看看官方的解释:

Animatable 是一个值容器,它可以在通过 animateTo 更改值时为值添加动画效果。该 API 支持 animate*AsState 的实现。它可确保一致的连续性和互斥性,这意味着值变化始终是连续的,并且会取消任何正在播放的动画。

Animatable 的许多功能(包括 animateTo)以挂起函数的形式提供。这意味着,它们需要封装在适当的协程作用域内。例如,您可以使用 LaunchedEffect 可组合项针对指定键值的时长创建一个作用域。

反正我刚开始看这段解释有点懵。

老样子,代码引入一步步深入学习:

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {val anim = Animatable()}}
}

注意:Animatable 导包的时候需要注意,不要选错:

在这里插入图片描述

抱歉,你这样写是会报错的:

在这里插入图片描述

很明显,Animatable 也需要用 remember 包起来:

在这里插入图片描述

提示我们需要加初始值,怎么填呢?我们可以看下 Animatable 的源码:

fun Animatable(initialValue: Float,visibilityThreshold: Float = Spring.DefaultDisplacementThreshold
)

需要一个 Float 类型的初始值:

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {val anim = remember { Animatable(48f) }}}
}

但并不是不允许用 dp,我们可以这样写也能满足 Animatable 的要求:

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {val anim = remember { Animatable(48.dp, Dp.VectorConverter) }}}
}

通过 Dp.VectorConverter 可以把 dp 转为 float。

接下来就可以配置动画了,直接调用 animateTo() 函数即可。

在这里插入图片描述

animateTo() 是个 suspend 函数,必须要在协程里面使用:

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {val anim = remember { Animatable(48.dp, Dp.VectorConverter) }LaunchedEffect(Unit) {anim.animateTo()}}}
}

现在只需要在 animateTo() 里面添加目标值即可。

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {val anim = remember { Animatable(48.dp, Dp.VectorConverter) }LaunchedEffect(Unit) {anim.animateTo(96.dp)}}}
}

到这里 Animatable 就创建好了,现在我们就要可以用起来了:

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)var big by mutableStateOf(false)setContent {val size = remember(big) { if (big) 96.dp else 48.dp }val anim = remember { Animatable(size, Dp.VectorConverter) }LaunchedEffect(big) {anim.animateTo(size)}Box(Modifier.size(anim.value).background(Color.Blue).clickable {big = !big})}}
}

让我解读下这段代码:

  1. Box 方块的 size 大小取决于 anim 的值,它的值会随着动画逐渐变化。
  2. 点击 Box 会改变 big 值,big 值变化会重新执行 LaunchedEffect 协程,animateTo 会执行,动画启动。
  3. big 从 false -> true,Box 动画由 48.dp -> 96.dp,big 从 true -> false,Box 动画由 96.dp -> 48.dp。

我们看下效果:

在这里插入图片描述

到这里,Animatable 的基本用法就讲完了。

不过 Animatable 还有个特别的功能,我们可以通过 snapTo() 定制动画的初始值。

例如下面的代码:

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)var big by mutableStateOf(false)setContent {val size = remember(big) { if (big) 96.dp else 48.dp }val anim = remember { Animatable(size, Dp.VectorConverter) }LaunchedEffect(big) {anim.snapTo(if (big) 192.dp else 0.dp)anim.animateTo(size)}Box(Modifier.size(anim.value).background(Color.Blue).clickable {big = !big})}}
}

我们添加了一句:anim.snapTo(if (big) 192.dp else 0.dp)

  1. Box 由小变大时,size 会瞬间到 0dp,然后从 0 -> 48dp
  2. Box 由大变小时,size 会瞬间到 192.dp,然后从 192.dp -> 96dp

看下效果:
在这里插入图片描述

这篇关于手把手教你写 Compose 动画 -- 流程定制型动画 API:Animatable()的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/466605

相关文章

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class Move : MonoBehaviour // 定义一个名为Move的类,继承自MonoBehaviour{private Rigidbo

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

如何更优雅地对接第三方API

如何更优雅地对接第三方API 本文所有示例完整代码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/third 我们在日常开发过程中,有不少场景会对接第三方的API,例如第三方账号登录,第三方服务等等。第三方服务会提供API或者SDK,我依稀记得早些年Maven还没那么广泛使用,通常要对接第三方

火语言RPA流程组件介绍--浏览网页

🚩【组件功能】:浏览器打开指定网址或本地html文件 配置预览 配置说明 网址URL 支持T或# 默认FLOW输入项 输入需要打开的网址URL 超时时间 支持T或# 打开网页超时时间 执行后后等待时间(ms) 支持T或# 当前组件执行完成后继续等待的时间 UserAgent 支持T或# User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器