Android中分析Jetpack Compose动画内部的实现原理
作者:李小白lt??????? 发布时间:2021-06-13 05:23:02
前言
Compose的动画Api用起来很简单,效果看起来很神奇,那么它内部到底是如何运转的呢?
使用动画的代码示例:
var isOffset by remember { mutableStateOf(false) }
val offsetAnimation by animateDpAsState(targetValue = if (isOffset) 100.dp else 0.dp)
Button(
onClick = { isOffset = !isOffset },
modifier = Modifier.offset(0.dp, offsetAnimation)
) {
Text(text = "点我进行位移")
}
看到有一个Boolean类型的isOffset状态,控制着offsetAnimation动画,然后动画又控制着Button的offset,最终实现了动画效果
我们主要就看一下animateDpAsState(animate*AsState)做了什么
跟一下animateDpAsState最后会走进animateValueAsState方法中:
方法内部创建了一个Animatable动画类
然后我们跟着上图的箭头看,在targetValue发生变化后,会通过channel来发送targetValue值的变化,然后launch启动一个协程,并在其中调用了animatable的animateTo方法
接着我们就看看Animatable类是如何做动画的:
主要就是内部持有一个AnimationState类型(State)的internalState 变量,然后我们接着上面的代码跟一下animateTo方法:
没什么好说的,包了一下targetValue,接着就调用了runAnimation方法,接着往下跟(截不下分成两张图):
主要逻辑就是endState.animate()
endState就是copy的Animatable中的AnimationState对象internalState,也就是动画的初始值
然后animation就是在animateTo方法中包装了动画目标值的对象
接着跟animate方法:
这个方法主要分为两部分,第一部分就是构建了一个AnimationScope,一个数据结构,用来存放动画需要的一些信息
第二个部分就是真正动画计算和生效的地方,doAnimationFrame
首先会在第一次创建AnimationScope的时候执行一次(或再一下帧执行一次,通过callWithFrameNanos方法)
然后会判断如果动画还未执行完毕,就一直循环(while),一帧一帧执行doAnimationFrame计算动画的值
doAnimationFrame方法代码:
其中通过时间等参数计算当前动画应该设置的值,包括lastFrameTimeNanos和value等属性,然后再最后调用updateState方法去将AnimationScope的值更新到AnimationState中
updatState方法代码:
这个state对象其实也就是animateDpAsState中的Animatable动画类中的AnimationState对象internalState
所以上面其实就是Compose中动画的简化流程
来源:https://juejin.cn/post/7118954918198640654


猜你喜欢
- hello,今天给大家带来一道算法题。这道算法题,是我目前为止,见过最难的一道题。那么到底是怎样的一道算法题呢?如下:题目:给定一个数组,
- 开发工具下载:Tomcat下载:wget http://learning.happymmall.com/tomcat/apache-tomc
- 一、ANR说明和原因1.1 简介ANR全称:Application Not Responding,也就是应用程序无响应。1.2 原因Andr
- 本文实例讲述了C#通过xpath查找xml指定元素的方法。分享给大家供大家参考。具体如下:orders.xml文档内容如下<?xml
- 网络工具类NetworkUtils,供大家参考,具体内容如下提供的方法:打开网络设置界面 openWirelessSettings判断网络是
- Logger来自log4j自己的包。如果用Logger.getLogger,需要一个log4j的jar包,用此方式你只能依log4j:Log
- Android Studio 是谷歌基于IntelliJ IDEA开发的安卓开发工具,有点类似 EcliPSe ADT,Android St
- 1.本文要解决的问题使用typora打开项目中的md文件2.预期效果选中文件,按下alt+t,调用typora打开此md文件3.IDEA配置
- 简介optional类是java8中引入的针对NPE问题的一种优美处理方式,源码作者也希望以此替代null。历史1965年,英国一位名为To
- OpenCV概述OpenCV做为功能强大的计算机视觉开源框架,包含了500多个算法实现,而且还在不断增加,其最新版本已经更新到3.2。其SD
- 相信大家一定遇到过某些App在手机桌面打开时会出现短暂或者几秒钟的白屏情况吧,没错那是应用程序启动后系统默认的背景色,此时应用的第一个Act
- 使用Scroller实现绚丽的ListView左右滑动删除Item效果这里来给大家带来使用Scroller的小例子,同时也能用来帮助初步解除
- 本文实例讲述了Android编程使用android-support-design实现MD风格对话框功能。分享给大家供大家参考,具体如下:首先
- JVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它和
- 四大函数式接口新时代的程序员:lambda 表达式,链式编程,函数式接口,Stream 流式计算函数式接口: 只有一个方法的接口@Funct
- 经度指示南北方向,纵向纬度指示东西方向,横向获取经纬度使用GPS权限:<uses-permission android:name=&q
- 为了提升编译速度,这几天用上了 AS 3.0 和 Gradle 3.0 插件,不得不说不论是 AS 3.0,还是 Gradle 3.0 都变
- 做了Android开发这么久了,经常会遇到一个问题是adb端口被占用,大家都知道Android默认的adb端口是5037,电脑上有一些应用的
- 本文实例讲述了Java基于socket实现简易聊天室的方法。分享给大家供大家参考。具体实现方法如下:chatroomdemo.javapac
- java金钱处理方法实例详解在支付行业中,涉及到对金钱的处理比较多。比如分转化成元、费率计算、手续费计算等等。1.分转化成元/** &nb