Jetpack Compose - 动画的几种结束机制

Posted datian1234

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jetpack Compose - 动画的几种结束机制相关的知识,希望对你有一定的参考价值。

作者:vivo祁同伟
链接:https://juejin.cn/post/7160878990347993101

动画的打断机制

所谓动画的打断机制 其实就是当某一个anim 在执行的时候,如果这个anim又跑去执行了其他的动画 那么之前的动画就会被打断, 注意是打断,而不是等前面一个动画执行完了再执行下一个

可以参考下面的这段代码, 本来我这个box 是要惯性滑动到某个位置的, 但是因为我在1100的时候 又开始了 另外一个anim的操作 所以在滑动到那个位置之前 我就往回惯性滑动了

也就是说在1000ms 开始执行的动画 被打断了,我们可以在try catch中 捕获到这个被打断的异常

setContent 
    val anim = remember 
        Animatable(0.dp, Dp.VectorConverter)
    

    val decay = rememberSplineBasedDecay<Dp>()
    LaunchedEffect(Unit) 
        delay(1000)
        // 动画的监听
        try 
            anim.animateDecay(3000.dp, decay)
         catch (e: CancellationException) 
            Log.e("wuyue","cancel my anim")
        
    

    LaunchedEffect(Unit) 
        delay(1100)
        // 动画的监听
        anim.animateDecay((-1000).dp, decay)
    

    Box(
        Modifier
            .padding(0.dp, anim.value, 0.dp, 0.dp)
            .size(100.dp)
            .background(Color.Green)
    ) 

    


下面这3个函数 会出现互相打断的情况

anim.animateDecay()
anim.animateTo()
anim.snapTo()

动画的停止

在某些时候,我们需要对某个进行中的动画发出信号让他停止执行

.clickable 
    lifecycleScope.launch
        anim.stop()
    

在compose中 我们可以方便的使用stop函数 即可,注意了 这个stop和anim函数一样 都是需要协程的执行环境的, 所以我们需要给他指定一个协程环境的scope

有人要问了 为啥这里不用launedEffect ,le 也是一个scope啊,

因为通常而言 le的环境是和compose的生命周期绑定在一起的,当你不想在compose重组的时候 重复执行某些操作 那就可以用 le,其他时候 其实不用le 更好

动画的边界条件

看下面这个代码

setContent 
    val anim = remember 
        Animatable(0.dp, Dp.VectorConverter)
    

    val decay = rememberSplineBasedDecay<Dp>()
    LaunchedEffect(Unit) 
        delay(1000)
        // 动画的监听
        try 
            anim.animateDecay(3000.dp, decay)
         catch (e: CancellationException) 
            Log.e("wuyue","cancel my anim")
        
    
    Box(
        Modifier
            .padding(anim.value, 0.dp, 0.dp, 0.dp)
            .size(100.dp)
            .background(Color.Green)
            .clickable 
                lifecycleScope.launch
                    anim.stop()
                
            
    ) 

    


同样是动画执行,但是这次 我们改变的是 paddingleft, 执行以后你会发现这个方块 出了屏幕了看不到了?

但是往往我们需要的是 想让这个方块在滑动的时候 到屏幕边缘就停止

所以我们需要给 动画设置一个边界条件,让他到了边界条件的时候就自动停止

那么显然 在这里 我们的边界条件就是让这个方块 滑动到屏幕边缘就立即结束 不要继续

进行如下修改即可

setContent 
    BoxWithConstraints 
        val anim = remember 
            Animatable(0.dp, Dp.VectorConverter)
        

        val decay = rememberSplineBasedDecay<Dp>()
        LaunchedEffect(Unit) 
            delay(1000)
            // 动画的监听
            try 
                anim.animateDecay(3000.dp, decay)
             catch (e: CancellationException) 
                Log.e("wuyue","cancel my anim")
            
        

        anim.updateBounds(upperBound = maxWidth - 100.dp)
        Box(
            Modifier
                .padding(anim.value, 0.dp, 0.dp, 0.dp)
                .size(100.dp)
                .background(Color.Green)
                .clickable 
                    lifecycleScope.launch 
                        anim.stop()
                    
                
        ) 

        

    


这里要注意的是 anim.updateBounds(upperBound = maxWidth - 100.dp)

这行代码madxWidth是BoxWithConstraints他的一个默认属性,我们可以直接使用, 为啥要-100.dp 这里要想明白

因为你想要的其实是 这个方块的右边距 顶着右边屏幕, 而我们一个view的坐标 是这个view的左顶点,所以 你的动画边距。最后算出来的距离 就必须得是 屏幕宽度-box的宽度

动画的返回值

还是上面的代码 ,我们稍微做一下修改, 给动画的执行加一个返回值

LaunchedEffect(Unit) 
    delay(1000)
    // 动画的监听
    try 
        val result = anim.animateDecay(3000.dp, decay)
        if (result.endReason == AnimationEndReason.BoundReached) 
            Log.e("wuyue","finish because endReason is boundReached")

        
     catch (e: CancellationException) 
        Log.e("wuyue","cancel my anim")
    

再看一下 动画执行到屏幕边缘以后的日志

这里能明确的看出来

到边缘停止的情况,是不会有异常的,反而我们还能在动画执行的返回值中 判断到这种情况

我们甚至可以利用这个方便的返回值,来很方便的实现 反弹效果

LaunchedEffect(Unit) 
    delay(1000)
    // 动画的监听
    try 
        var result = anim.animateDecay(3000.dp, decay)
        while (result.endReason == AnimationEndReason.BoundReached) 
            result = anim.animateDecay(-result.endState.velocity, decay)
        
     catch (e: CancellationException) 
    


anim.updateBounds(upperBound = maxWidth - 100.dp, lowerBound = 0.dp)

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。

相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

一、架构师筑基必备技能

1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……

二、Android百大框架源码解析

1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程

三、Android性能优化实战解析

  • 腾讯Bugly:对字符串匹配算法的一点理解
  • 爱奇艺:安卓APP崩溃捕获方案——xCrash
  • 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
  • 百度APP技术:Android H5首屏优化实践
  • 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
  • 携程:从智行 Android 项目看组件化架构实践
  • 网易新闻构建优化:如何让你的构建速度“势如闪电”?

四、高级kotlin强化实战

1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》

  • 从一个膜拜大神的 Demo 开始

  • Kotlin 写 Gradle 脚本是一种什么体验?

  • Kotlin 编程的三重境界

  • Kotlin 高阶函数

  • Kotlin 泛型

  • Kotlin 扩展

  • Kotlin 委托

  • 协程“不为人知”的调试技巧

  • 图解协程:suspend

五、Android高级UI开源框架进阶解密

1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南

六、NDK模块开发

1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习

七、Flutter技术进阶

1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)

八、微信小程序开发

1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……

全套视频资料:

一、面试合集

二、源码解析合集


三、开源框架合集


欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓

以上是关于Jetpack Compose - 动画的几种结束机制的主要内容,如果未能解决你的问题,请参考以下文章

Jetpack Compose 中使用 Lottie 动画

Jetpack Compose 列表的展开与收起颜色动画效果

Jetpack Compose 从入门到入门

Jetpack Compose 中可绘制动画的替代方法是啥

Jetpack Compose 从入门到入门

Jetpack Compose 从入门到入门