当前位置: 首页 > news >正文

手把手教你写 Compose 动画 -- 过渡动画 API:Transition

📓 Transition


updateTransiton 是 Compose 中实现过渡动画的关键 API 。所谓过渡动画,即当依赖的某个状态发生改变时连锁发生的一系列动画效果。前面我们所提到的 Animate*AsState 与 Animatable 都是针对一个属性进行变换的,而 updateTransition 允许开发者将多个属性数值绑定到一个状态,当这个状态发生改变时,多个属性同时进行变换。

探索新技术的最佳方式是尝试它们,我们先构建一个简单场景:

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {Column (modifier = Modifier.fillMaxWidth(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally) {Spacer(modifier = Modifier.height(20.dp))Image(painter = painterResource(R.drawable.pingtouge),contentDescription = null,modifier = Modifier.size(90.dp).clip(shape = CircleShape).border(color = Color.Red, shape = CircleShape, width = 3.dp))Button(onClick = {}) {Text(text = "切换")}}}}
}

这段代码不难理解,效果如下:

在这里插入图片描述

现在我们假设一个需求场景:

  1. 图片大小 size 需要变化:小图片(90dp)、大图片(130dp)
  2. 图片边框颜色 color 需要变化:绿色、红色
  3. 对应关系:小图片绿色边框,大图片红色边框

现在我们开始讲解如何用 Transition 实现这个动画效果。

  1. 对于 updateTransition,状态可以是任何数据类型。我们自定义一个枚举类型:
private enum class ImageState {Small, Large
}
  1. 创建一个处理状态的变量:
var imageState by remember { mutableStateOf(ImageState.Small) }
  1. 创建 Transition 对象

我们先看下 updateTransition() 函数:

@Composable
fun <T> updateTransition(targetState: T,label: String? = null
): Transition<T>

它需要两个参数:

⇒ targetState:状态变量,当它被更改时,动画会进行。

⇒ label:动画的标签。

这里的状态就是我们之前定义的:imageState,所以我们可以像下面这样写:

val transition = updateTransition(targetState = imageState, label = "ImageState Transition")

updateTransition() 会返回一个 Transition 对象。

现在,我们可以使用 transition 对象来调用 animate* 函数。它们帮助我们为不同的 value 值制作动画。比如:
animateColor()、animateDp()、animateInt()、animateSize() 等。

  1. 定制边框颜色动画
val borderColor by transition.animateColor(label = "ImageState Color Transition") {when (it) {ImageState.Small -> Color.GreenImageState.Large -> Color.Magenta}
}
  1. 定制图片尺寸动画
val size by transition.animateDp(label = "ImageState Size Transition") {when (it) {ImageState.Small -> 90.dpImageState.Large -> 130.dp}
}

我们为每个属性状态(borderColor、size)声明了其在不同状态(ImageState.Small、ImageState.Large)时所对应的值,当过度动画所依赖状态(imageState)发生改变时,其中每个属性状态都会得到相应的更新。

  1. 应用到组件上(完整代码)

接下来,我们只需将创建的属性状态应用到我们的组件中即可:

private enum class ImageState {Small, Large
}class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {var imageState by remember { mutableStateOf(ImageState.Small) }val transition = updateTransition(targetState = imageState, label = "ImageState Transition")val borderColor by transition.animateColor(label = "ImageState Color Transition") {when (it) {ImageState.Small -> Color.GreenImageState.Large -> Color.Magenta}}val size by transition.animateDp(label = "ImageState Size Transition") {when (it) {ImageState.Small -> 90.dpImageState.Large -> 130.dp}}Column (modifier = Modifier.fillMaxWidth(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally) {Spacer(modifier = Modifier.height(20.dp))Image(painter = painterResource(R.drawable.pingtouge),contentDescription = null,modifier = Modifier.size(size).clip(shape = CircleShape).border(color = borderColor, shape = CircleShape, width = 3.dp))Button(onClick = {imageState = if (imageState == ImageState.Small) {ImageState.Large} else {ImageState.Small}}) {Text(text = "切换")}}}}
}

效果如下:

在这里插入图片描述

相关文章:

  • 微信小程序 - PC端选择ZIP文件
  • 《Vue.js设计与实现》—Vue3响应系统的原理
  • 腾讯地图系列(二):微信小程序添加插件(三种方法)以及插件AppId获取
  • ArcGIS无法绘制一个或多个图层
  • 基于以太坊的智能合约开发Solidity(数组提升篇)
  • 智能时代:互联网+如何改变我们的生活与工作
  • STM32CubeIDE串口空闲中断实现不定长数据接收
  • 华为OD机试真题-智能成绩表-2023年OD统一考试(C卷)
  • 线性代数入门与学习笔记
  • ViT:视觉 Transformer
  • VS Code 上已达250万 Java 开发者!微软和红帽一起公布 VS Code Java 未来六个月路线图
  • 机器学习实验三:支持向量机模型
  • 连锁零售企业如何优化网络性能?
  • 【开源】基于Vue+SpringBoot的教学资源共享平台
  • Redis研学-三种特殊类型的常用命令
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • 0基础学习移动端适配
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • Fastjson的基本使用方法大全
  • Fundebug计费标准解释:事件数是如何定义的?
  • Github访问慢解决办法
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • Javascript 原型链
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • nginx 配置多 域名 + 多 https
  • orm2 中文文档 3.1 模型属性
  • OSS Web直传 (文件图片)
  • Redis中的lru算法实现
  • Transformer-XL: Unleashing the Potential of Attention Models
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • Vue小说阅读器(仿追书神器)
  • windows下使用nginx调试简介
  • 成为一名优秀的Developer的书单
  • 二维平面内的碰撞检测【一】
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 关于字符编码你应该知道的事情
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 如何设计一个比特币钱包服务
  • 一些css基础学习笔记
  • elasticsearch-head插件安装
  • 容器镜像
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ![CDATA[ ]] 是什么东东
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (二)WCF的Binding模型
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (三)elasticsearch 源码之启动流程分析
  • (三)uboot源码分析
  • (十一)手动添加用户和文件的特殊权限
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • ***监测系统的构建(chkrootkit )
  • .bat文件调用java类的main方法