Compose低级别API动画指南

Google官方为Compose提供的动画API与原生View体系的动画API相差甚远,目前总共分为四类:高级别动画API、低级别动画API、自定义动画、手势和动画(其他),下图是官方提供的流程指示图,以供根据不同使用场景来选择相应动画:

image.png

animate*AsState

此函数是Compose中的简单动画API,也是低级别动画API,主要用于实现单一属性的动画效果,其能处理的相关属性如下:Float、Color、Dp、Size、Offset、Rect、Int、IntOffset 和 IntSize。使用方式只需将目标值封装在 animate*AsState()中即可。例如以下示例:

@Composable
fun showAnim(){
    val enabled = remember {
        mutableStateOf(true)
    }
    val alpha: Float by animateFloatAsState(if (enabled.value) 1f else 0.2f)
    Box(
        Modifier.fillMaxSize()
            .graphicsLayer(alpha = alpha)
            .background(Color.Red)
            .clickable { enabled.value = !enabled.value }
    )
}

代码理解起来并不难,通过animateFloatAsState()函数来改变控件的alpha值(alpha值为Float类型,所以是函数是animateFloatAsState),在点击事件里监听到点击则改变对应变量,通过嵌套了remember的mutableStateOf函数对界面进行重组,于是页面的alpha在0.2f和1.f之间来回改变。对应效果如下:

Anima-1.gif

以此类推,改变颜色的函数API则是animateColorAsState(),改变尺寸的函数则是animateSizeAsState(),等等。例如下述的颜色改变动画:

@Composable
fun showAnim(){
    val enabled = remember {
        mutableStateOf(true)
    }
    val color = animateColorAsState(if (enabled.value) Color.Blue else Color.Yellow)
    Box(
        Modifier.fillMaxSize()
            .background(color.value)
            .clickable { enabled.value = !enabled.value }
    )
}

其效果为:
Anim-2.gif

此函数不需要创建任何动画类的实例,也不需要处理中断操作。系统会在后台创建并记录一个动画对象(Animatable实例),并将你设置的第一个目标值设为初始值。此后,只要目标值改变了,系统就会自动播放此目标值的动画。如果这时已有动画在播放,系统将从其当前值(和速度)开始向目标值播放动画(不会从初始值重新开始)。在播放动画期间,这个可组合项会重组,并返回已更新的每帧动画值。

Animatable

一个动画值的包装器,主要用于实现帧动画。可以在通过调用animateTo(),监听animateTo()值改变时进行相应的动画效果。在某些情况下可以指达到同animate*AsState一样的效果,但如果此动画在执行过程中如果再次执行则会中断当前动画。示例如下:

fun showAnim(){
    val enabled = remember {
        mutableStateOf(true)
    }
    val color = remember { Animatable(Color.Green) }
    LaunchedEffect(enabled.value) {
        color.animateTo(if (enabled.value) Color.Yellow else Color.Red)
    }
    Box(Modifier.fillMaxSize().background(color.value)
        .clickable {
            enabled.value = !enabled.value
        })
}

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

Anim-3.gif

与 animate*AsState 相比,Animatable 的初始值可以与第一个目标值不同,上例就是三个颜色的改变。此外,Animatable 还提供更多操作(即 snapTo 和 animateDecay)。snapTo 可立即将当前值设为目标值。如果动画需要与其他状态(如触摸事件)同步,则可以使用snapTo。animateDecay 用于启动播放从给定速度变慢的动画。有兴趣的可以试试,这里不做赘述。

updateTransition

Transition 可管理一个或多个动画,并在多个状态之间同时运行这些动画(有没有想起5.0的场景变换动画,但这是两个东西)。updateTransition 可创建并记住 Transition 的实例,并更新其状态,达到实现多个动画组合的效果。通俗来讲就是,通知单个或多个值发生变化来设置动画。当状态发生改变时,多个值要一起发生变化。官方推荐使用枚举来定义多个状态以确保类型安全,例如以下示例:

fun showAnim() {
    val targetState = remember {
        mutableStateOf(BoxState.Collapsed)
    }
    val transition = updateTransition(
        targetState = targetState
    )

    val rect by transition.animateRect { state ->
        when (state.value) {
            BoxState.Collapsed -> Rect(0f, 0f, 100f, 100f)
            BoxState.Expanded -> Rect(100f, 100f, 300f, 300f)
        }
    }
    val offsets by transition.animateDp { state ->
        when (state.value) {
            BoxState.Collapsed -> 2.dp
            BoxState.Expanded -> 0.dp
        }
    }
    val color by transition.animateColor {state ->
        when(state.value){
            BoxState.Expanded->Color.Red
            BoxState.Collapsed->Color.Yellow
        }
    }
    Column(
        Modifier
            .padding(16.dp)
            .size(300.dp)) {
        Button(onClick = { if (targetState.value == BoxState.Expanded) targetState.value =
            BoxState.Collapsed else targetState.value = BoxState.Expanded}) {
            Text(text = "updateTransition Animation")
        }
        Box(modifier = Modifier.size(rect.width.dp, rect.height.dp)
            .offset(x=offsets)
            .background(color = color))
    }
}

private enum class BoxState {
    Collapsed,
    Expanded
}

对应效果为:

Anim - 4.gif

可以看到,点击按钮之后,页面在Collapsed和Expanded两种状态来回切换。不仅如此,Transition中有很多其他扩展函数:
image.gif
可在实际开发中根据不同需求场景选择。

rememberInfiniteTransition

InfiniteTransition主要是在Compose中用于实现重复动画,它可以像 Transition 一样保存一个或多个子动画,与updateTransition不同的是,这些动画一进入组合阶段就开始运行,除非被移除,否则不会停止。使用方式:使用 rememberInfiniteTransition 创建 InfiniteTransition 实例,通过 animateColor、animatedFloat 或 animatedValue 添加子动画,同时,通过 infiniteRepeatable 指定动画规范。例如如下示例:

fun showAnim() {
    val mInfiniteTransition = rememberInfiniteTransition()
    val state by mInfiniteTransition.animateColor(
        initialValue = Color.Red,
        targetValue = Color.Green,
        animationSpec = infiniteRepeatable(
            animation = tween(durationMillis = 800,easing = FastOutSlowInEasing),
            repeatMode = RepeatMode.Reverse
        ))
    Box(
        Modifier
            .size(200.dp)
            .background(state)
    )
}

对应效果为:

Anim - 5.gif

可见这动画一直不断运行,800ms一间隔时间,颜色来回切换,这类动画除非被移除,否则不会自动停止。

TargetBasedAnimation

开发者可直接使用的最低级 API,主要用于控制动画的执行时间。updateTransition以及rememberInfiniteTransition以及Animatable动画都是由该api封装得来,可使用此动画的场景都可用animateTo()替代,这里就不再赘述。当然,以上KPI不一定适合所有场景,与此对应还有高级别动画API(下一篇讲解)。

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

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

相关文章

PMDG 737

在Simbrief中生成计划后下载两个文件 放到A:\Xbox\Community\pmdg-aircraft-738\Config\Flightplans中

深度学习疆界:探索基本原理与算法,揭秘应用力量,展望未来发展与智能交互的新纪元

目录 什么是深度学习 深度学习的基本原理和算法 深度学习的应用实例 深度学习的挑战和未来发展方向 挑战 未来发展方向 深度学习与机器学习的关系 深度学习与人类的智能交互 什么是深度学习 深度学习是一种基于神经网络的机器学习方法,旨在模仿人类大脑分析…

LabVIEW虚拟测试与分析仪

LabVIEW虚拟测试与分析仪 在现代工程技术领域,虚拟仪器的开发和应用已成为一种趋势。利用LabVIEW软件平台开发的虚拟测试与分析仪器进行展开,实现工程测试和分析中的实际需求。通过结合LabVIEW的强大功能和灵活性,成功实现了一套高效、精确的…

各指针含义区分

一、char *a P109: (1)(变量)指针变量:指针变量,即指针的定义:用来存放指针的变量。指向的是变量,且可以改变其指向的地址。P104 char *a (2)(变量)指针常量:指针常量,指向的是变量首字节的地址&#xff…

算法基础——单调栈,单调队列

目录 1.单调栈 例题:【模板】单调栈 例题:求和 2.单调队列 例题:滑动窗口 1.单调栈 例题:【模板】单调栈 可以想象出一个柱状图,值越大,这个柱子越高 以此题的样例为例: 第一个数为7,想…

【Java程序员面试专栏 分布式中间件】ElasticSearch 核心面试指引

关于ElasticSearch 部分的核心知识进行一网打尽,包括ElasticSearch 的基本概念,基本架构,工作流程,存储机制等,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 基础概念 从数据分类入手,考察全文索引的基本概念 现实世界中数据有哪…

yolov5配置教程

yolov5 yolov5 notepad notepad 直接下一步就可以 Git Git 取消勾选 修改默认编辑器为npp 其他都直接下一步 python3.8.1 python3.8.1 主要勾选添加环境变量 其他下一步即可 Miniconda Miniconda 其他下一步 然后添加系统环境变量 Pycharm Pycharm 把这个界面所…

MPLAB V8.92 printf

Compile error “A heap is required, but has not been specified” Set printf function #if 0 //for UART1 int fputc(int ch, FILE *f) { IFS1bits.U2TXIF 0; // if (runConfig.printOn 1) { // usart_data_transmit(USART0, (uint8_t)ch); U2TXREG ch; // while (RESE…

linux(阿里云)安装pytorch

目录 环境 安装步骤 1 检查python3和pip3是否已经安装 2 安装pytorch 3 安装完毕,检查pytorch版本 环境 阿里云 ubuntu 22.04 UEFI版 64位 安装步骤 1 检查python3和pip3是否已经安装 输入下面两条指令: python3 --version pip --version 检…

Nvm安装(windows版)

1、nvm 是什么 (1)nvm(Node.js version manager) 是一个命令行应用,可以协助您快速地 更新、安装、使用、卸载 本机的全局 node.js 版本。 (2)有时候,我们可能同时在进行多个项目开发,而多个项…

书生·浦语大模型第六课作业

面向GPU的环境安装 conda create --name opencompass --clone/root/share/conda_envs/internlm-base source activate opencompass git clone https://github.com/open-compass/opencompass cd opencompass pip install -e . 数据准备 # 解压评测数据集到 data/ 处 cp /shar…

神经网络 | CNN 与 RNN——深度学习主力军

Hi,大家好,我是半亩花海。本文主要将卷积神经网络(CNN)和循环神经网络(RNN)这两个深度学习主力军进行对比。我们知道,从应用方面上来看,CNN 用于图像识别较多,而 RNN 用于…

c++阶梯之类与对象(下)

前文: c阶梯之类与对象(上)-CSDN博客 c阶梯之类与对象(中)-CSDN博客 c阶梯之类与对象(中)< 续集 >-CSDN博客 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时&a…

Go教程-什么是编程?

什么是编程,这是个有趣的话题。 编程是什么 编程,字面意思即编写程序,即通过既定的关键字,来描述你的想法,并让计算机的各个部件按照你的想法来做事。 这里计算机的各个部件通常来说,指的是CPU和IO设备。…

对进程与线程的理解

目录 1、进程/任务(Process/Task) 2、进程控制块抽象(PCB Process Control Block) 2.1、PCB重要属性 2.2、PCB中支持进程调度的一些属性 3、 内存分配 —— 内存管理(Memory Manage) 4、线程(Thread)…

linux系统配置zabbix监控agent端

目录 客户端配置 启动服务 浏览器工具设置 创建主机群组 创建主机 创建监控项 ​编辑 ​编辑 创建触发器 查看监控 客户端配置 rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm # yum clean allyum install -y zab…

【python之美】减少人工成本之批量拿取文件名保存_4

获取文件名保存 准备工作: 上代码: import ospath "C:\\Users\\Administrator\\Desktop\\text\\" file_names os.listdir(path) print(file_names)i 1 for file_name in file_names:name file_name.split(_)[0]print(name)new_name name "_修改后第&qu…

配置Juniper虚墙vSRX基于策略的IPsec VPN(WEB方式)

正文共:1444 字 18 图,预估阅读时间:2 分钟 关于IPsec VPN,我们已经有一个合集了(IPsec VPN)。之前接触比较多的是H3C的IPsec VPN,后来接触的厂家多了,才发现大家的模型或者叫法还是…

相机图像质量研究(20)常见问题总结:CMOS期间对成像的影响--全局快门/卷帘快门

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结:光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结:光学结构对成…

C++:stack queue - 容器适配器

C:容器适配器 容器适配器概念stackqueuedeque 容器适配器概念 容器适配器是在C标准库中提供的一种容器的封装。它们提供了一种统一的接口,使得不同类型的容器可以以相似的方式被使用。容器适配器有三种类型:栈(stack)…