手把手教你写 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

相关文章

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

使用Go实现文件复制的完整流程

《使用Go实现文件复制的完整流程》本案例将实现一个实用的文件操作工具:将一个文件的内容完整复制到另一个文件中,这是文件处理中的常见任务,比如配置文件备份、日志迁移、用户上传文件转存等,文中通过代码示例... 目录案例说明涉及China编程知识点示例代码代码解析示例运行练习扩展小结案例说明我们将通过标准库 os

Ubuntu 24.04启用root图形登录的操作流程

《Ubuntu24.04启用root图形登录的操作流程》Ubuntu默认禁用root账户的图形与SSH登录,这是为了安全,但在某些场景你可能需要直接用root登录GNOME桌面,本文以Ubuntu2... 目录一、前言二、准备工作三、设置 root 密码四、启用图形界面 root 登录1. 修改 GDM 配

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

Spring Security中用户名和密码的验证完整流程

《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 首先创建了一个UsernamePasswordAuthenticationTChina编程oken对象,这是S

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4