我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android Compose之Animatable动画停止怎么使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android Compose之Animatable动画停止怎么使用

本篇内容主要讲解“Android Compose之Animatable动画停止怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android Compose之Animatable动画停止怎么使用”吧!

打断停止

顾名思义即动画在运行过程中被打断,那么是被什么打断呢?被同一个 Animatable的另一个动画打断,简单的说就是当 Animatable在执行某一个动画的过程中,此时再使用同一个 Animatable 去开启另一个动画,此时就会打断正在运行中的动画,即停止正在运行中的话执行新的动画。

那么为什么要打断正在运行中的动画呢?不能两个动画一起执行吗?假设一个动画是将方块移动到 200dp 的位置,另一个动画是将方块移动到 0dp 的位置,如果不会被打断两个动画可以同时执行,那就会出现方块一会儿往 200dp 位置一会儿往 0dp 移动的闪烁情况,显然动画效果不符合预期,所以被设计成了后一个动画会打断前一个动画。

下面就用一个实例演示动画的打断,代码如下:

// 方块颜色,默认为蓝色var backgroundColor by remember { mutableStateOf(Color.Blue) }// 动画实例val animatable = remember { Animatable(10.dp, Dp.VectorConverter) }// 获取协程作用域val scope = rememberCoroutineScope()Box {    // 动画方块    Box(        Modifier            // 使用动画值            .padding(start = animatable.value, top = 30.dp)            .size(100.dp, 100.dp)            .background(backgroundColor)            .clickable { // 点击事件                // 启动动画                scope.launch {                    animatable.animateTo(200.dp,                        // 为了方便看到效果,动画时间设置为 1000ms                                         animationSpec = tween(durationMillis = 1000)                    )                }            }    )    // 按钮,用于开启新动画    Button(onClick = {        // 修改方块颜色,方便观察区分两个动画        backgroundColor = Color.Cyan        // 启动新动画        scope.launch {            animatable.animateTo(50.dp, animationSpec = tween(durationMillis = 1000))        }    }, Modifier.padding(top = 170.dp, start = 70.dp)) {        Text(text = "Next", style = TextStyle(fontSize = 10.sp))    }}

界面上添加了一个方块和一个按钮,点击方块执行动画移动到 200dp 位置,点击按钮执行动画移动到 50dp 位置,为了区分两个动画动画执行时为方块设置了不同的颜色

从上面的效果可以看出,对同一个 Animatable开启新的动画确实会打断正在运行的动画。

除了上面演示的 animateTo可以打断动画以外,AnimatablesnapToanimateDecay同样可以打断动画。

主动停止

前面介绍的是新动画打断正在运行的动画,那么如果我们想主动停止一个Animatable动画该怎么办呢?很简单,Animatable提供了stop方法用于停止动画。

示例代码如下:

var backgroundColor by remember { mutableStateOf(Color.Blue) }// 动画实例val animatable = remember { Animatable(10.dp, Dp.VectorConverter) }val scope = rememberCoroutineScope()Box {    // 动画方块    Box(        Modifier            // 使用动画值            .padding(start = animatable.value, top = 30.dp)            .size(100.dp, 100.dp)            .background(backgroundColor)            .clickable { // 点击事件,开启动画                scope.launch {                    animatable.animateTo(200.dp,                    // 为了方便观察动画效果,动画时长设置为 1000ms                        animationSpec = tween(durationMillis = 1000)                    )                }            }    )    // 停止按钮    Button(onClick = {        // 修改方块颜色        backgroundColor = Color.Cyan        // 停止动画        scope.launch {            animatable.stop()        }    }, Modifier.padding(top = 170.dp, start = 70.dp)) {        Text(text = "Stop", style = TextStyle(fontSize = 10.sp))    }}

需要注意的是 stop方法也是一个挂起函数,需要在协程中执行

触达边界停止

Animatable可以通过 updateBounds函数为动画设置边界值,当动画运动到边界时会立即停止动画,updateBounds定义如下:

fun updateBounds(lowerBound: T? = this.lowerBound, upperBound: T? = this.upperBound)

updateBounds方法有两个参数 lowerBoundupperBound分别为动画的边界下限值和上限值,默认为 null即不做限制,可以单独设置上限和下限的值,当设置对应值后,动画运行过程中动画值达到边界值时就会立即停止动画。

示例代码如下:

// 创建状态 通过状态驱动动画var moveToRight by remember { mutableStateOf(false) }// 动画实例val animatable = remember { Animatable(10.dp, Dp.VectorConverter) }// 设置动画边界animatable.updateBounds(lowerBound = 10.dp, upperBound = 200.dp)val scope = rememberCoroutineScope()Box(    Modifier        // 使用动画值        .padding(start = animatable.value, top = 30.dp)        .size(100.dp, 100.dp)        .background(Color.Blue)        .clickable { // 点击事件            // 修改状态            moveToRight = !moveToRight            scope.launch {                // 执行动画                animatable.animateTo(                    // 根据状态设置动画的目标值,分别是向右到 400dp 和 向左到 -100dp 位置                    if (moveToRight) 400.dp else -100.dp,                    animationSpec = tween(durationMillis = 1000)                )            }        })

上面代码分别设置了下限值为 10dp、上限值为 200dp,同时动画目标值分别设置为 -100dp 和 400dp:

可以看出来,虽然动画目标设置分别设置了 -100dp 和 400dp,但是因为我们设置了边界值为 10dp 和 200dp,所以动画向右运动时到达边界值即 200dp 位置时就停止了,向左同样的到达边界值 10dp 也停止了动画,这就是动画边界的作用。

多维边界

之前介绍了 Compose 动画是可以作用于多维数值的,比如作用于 Size、Offset、React 等数据时就是多维的动画,此时对动画设置边界后,动画目标值只要有其中一维的数值达到边界就会立即停止,并不会等到所有维的数值都达到边界才会停止。

下面用一个示例来举例说明,还是上面的方块动画,上面只进行了横向的动画,如果我们要同时进行横向和竖向的动画,可以使用 Offset 来进行动画,然后对其进行边界设置来观察效果,代码如下:

// 创建状态 通过状态驱动动画var moveToRight by remember { mutableStateOf(false) }// 动画实例val animatable = remember { Animatable(Offset(10f, 30f), Offset.VectorConverter) }// 设置边界值,下限:Offset(10f, 30f)  上限:Offset(400f, 200f)animatable.updateBounds(lowerBound = Offset(10f, 30f), upperBound = Offset(400f, 200f))val scope = rememberCoroutineScope()Box {    Box(        Modifier            // 使用动画值            .padding(start = animatable.value.x.dp, top = animatable.value.y.dp)            .size(100.dp, 100.dp)            .background(Color.Blue)            .clickable {                // 修改状态                moveToRight = !moveToRight                scope.launch {                    animatable.animateTo(                        // 根据状态设置动画的目标值                        // 分别为向右和向下的 Offset(400f,400f)                        // 向上和向左的 Offset(-100f,0f)                        if (moveToRight) Offset(400f,400f) else Offset(-100f,0f),                        animationSpec = tween(durationMillis = 1000)                    )                }            }    )}

可以发现,上限设置为 Offset(400f, 200f)即 x 轴最大为 400dp、y 轴最大为 200dp,动画目标值为Offset(400f,400f),当方块移动到 y 坐标为 200dp 时 y 坐标的值达到边界值,动画就停止了,此时 x 坐标值并未达到边界值。同样的往回执行时 x 坐标先触发达到边界值 10dp 时停止了动画。

如果就是想让动画都达到边界才停止,此时不应该采用多维动画的方式,而是应该使用多个单维动画,对其分别设置边界即可。

动画停止监听

动画停止可分为异常停止和正常停止,其中打断和主动停止动画属于异常停止,动画运行完成或达到边界后停止属于正常停止。

异常停止

一个动画打断另一个动画,或调用 stop主动停止动画都属于异常停止,此时动画会抛出 CancellationException的异常,在代码中可通过捕获该异常来监听动画的异常停止,代码如下:

scope.launch {    try {        // 异常停止时动画会抛出异常,不会正常返回动画结果        val animationResult = animatable.animateTo(200.dp,            animationSpec = tween(durationMillis = 1000)        )        // 动画异常停止时会抛出异常,下面的代码不会被执行        // do something    } catch (e: CancellationException) {        Log.e("ANIMATOIN", "动画异常停止")    }}

正常停止

动画触达边界停止属于正常停止,此时动画会正常返回结果,从结果中的 endReason可判断动画是否为触达边界停止,代码如下:

scope.launch {    val animationResult = animatable.animateTo(200.dp,        animationSpec = tween(durationMillis = 1000)    )    // 判断动画是否触达边界停止    if(animationResult.endReason == AnimationEndReason.BoundReached){        // do something    }}

同时动画结果还能拿到动画停止时的速度等数据,这样就能通过监听动画边界停止进行自定义的处理,比如结合上一篇介绍的衰减动画让动画到达边界后反向运动,代码如下:

@Preview@Composablefun AnimationBound3() {    // 动画实例    val animatable = remember { Animatable(10.dp, Dp.VectorConverter) }    // 设置边界值    animatable.updateBounds(upperBound = 200.dp, lowerBound = 10.dp)    val scope = rememberCoroutineScope()    val splineBasedDecay = rememberSplineBasedDecay<Dp>()    Box(        Modifier            // 使用动画值            .padding(start = animatable.value, top = 30.dp)            .size(100.dp, 100.dp)            .background(Color.Blue)            .clickable {                scope.launch {                    // 启动动画,设置初始速度为 3000dp                    val animationResult = animatable.animateDecay(3000.dp, splineBasedDecay)                    // 判断是否为到达边界停止                    if(animationResult.endReason == AnimationEndReason.BoundReached){                        // 执行反向动画,初始速度取动画结束时速度的负数                        reverseAnimation(animatable, -animationResult.endState.velocity, splineBasedDecay)                    }                }            }    )}/// 反向执行动画private suspend fun reverseAnimation(    animatable: Animatable<Dp, AnimationVector1D>,    initialVelocity: Dp,    splineBasedDecay: DecayAnimationSpec<Dp>) {    val result =  animatable.animateDecay(initialVelocity, splineBasedDecay)    // 判断是边界停止时递归执行反向动画直到动画非边界停止    if(result.endReason == AnimationEndReason.BoundReached){        reverseAnimation(animatable, -result.endState.velocity, splineBasedDecay)    }}

到此,相信大家对“Android Compose之Animatable动画停止怎么使用”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android Compose之Animatable动画停止怎么使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android Compose之Animatable动画停止怎么使用

本篇内容主要讲解“Android Compose之Animatable动画停止怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android Compose之Animatable动画停止怎
2023-07-05

Android Compose衰减动画Animatable怎么使用

这篇文章主要讲解了“Android Compose衰减动画Animatable怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android Compose衰减动画Animatable
2023-07-04

Android Compose状态改变动画animateXxxAsState怎么使用

今天小编给大家分享一下Android Compose状态改变动画animateXxxAsState怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获
2023-07-04

Android动画之TranslateAnimation怎么使用

TranslateAnimation是Android系统提供的一种平移动画效果,可以让View在屏幕上沿着指定的路径移动。下面是使用TranslateAnimation的步骤:创建TranslateAnimation对象:Translate
Android动画之TranslateAnimation怎么使用
2024-03-01

SQL SERVER服务怎么使用批处理启动/停止

小编给大家分享一下SQL SERVER服务怎么使用批处理启动/停止,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!那么就让sql server等一些非windows
2023-06-08

Vue3之怎么使用js实现动画

这篇“Vue3之怎么使用js实现动画”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue3之怎么使用js实现动画”文章吧。概
2023-07-05

Android 中怎么利用多线程重复启动与停止服务

这篇文章将为大家详细讲解有关Android 中怎么利用多线程重复启动与停止服务,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Android 多线程实现重复启动与停止的服务多线程环境下为了避免
2023-05-30

怎么使用Shell脚本启动/停止Java的jar程序

小编给大家分享一下怎么使用Shell脚本启动/停止Java的jar程序,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!启动脚本:start_upload.sh#!/
2023-06-09

怎么使用jQuery实现一个图片不停旋转动画效果

这篇文章主要介绍“怎么使用jQuery实现一个图片不停旋转动画效果”,在日常操作中,相信很多人在怎么使用jQuery实现一个图片不停旋转动画效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么使用jQuer
2023-07-05

Android中怎么使用ListView实现滚轮动画效果

今天就跟大家聊聊有关Android中怎么使用ListView实现滚轮动画效果,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。 private
2023-05-31

Android怎么使用cos和sin绘制复合曲线动画

这篇文章将为大家详细讲解有关Android怎么使用cos和sin绘制复合曲线动画,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在开发新需求的时候,设计给了一份类似这样的动画:看着不难,即使一遍看不懂,嘿嘿
2023-06-14

使用CSS 属性怎么实现按钮悬停边框和背景动画集合

使用CSS 属性怎么实现按钮悬停边框和背景动画集合?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。心属性opacity: .999 使元素产生一个层叠上下文,这样按钮6和8的动画
2023-06-08

怎么在Android中使用ScrollView实现一个下拉弹回动画效果

本篇文章给大家分享的是有关怎么在Android中使用ScrollView实现一个下拉弹回动画效果,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Android是什么Android
2023-05-30

Android怎么使用圆形揭露动画巧妙地隐藏或显示View

这篇文章主要介绍“Android怎么使用圆形揭露动画巧妙地隐藏或显示View”,在日常操作中,相信很多人在Android怎么使用圆形揭露动画巧妙地隐藏或显示View问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答
2023-06-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录