Android Compose 创建摇动动画

2024-01-20

我正在尝试在 Jetpack Compose 中制作形状的晃动动画。我想在用户输入无效的 Pin 码时使用此动画来显示错误。但我能找到的只是滑入、滑出动画和一些缩放动画。我有什么想法可以做到这一点吗?

Update:在@Thracian 回答之后。我使用如下代码,水平摇动我的物品:

fun Modifier.shake(enabled: Boolean, onAnimationFinish: () -> Unit) = composed(
    factory = {
        val distance by animateFloatAsState(
            targetValue = if (enabled) 15f else 0f,
            animationSpec = repeatable(
                iterations = 8,
                animation = tween(durationMillis = 50, easing = LinearEasing),
                repeatMode = RepeatMode.Reverse
            ),
            finishedListener = { onAnimationFinish.invoke() }
        )

        Modifier.graphicsLayer {
            translationX = if (enabled) distance else 0f
        }
    },
    inspectorInfo = debugInspectorInfo {
        name = "shake"
        properties["enabled"] = enabled
    }
)

不幸的是,Gif 比实际动画慢,但它给出了结果的想法。

这可以通过多种方式来完成。您应该在短时间内更改scaleX或scaleY或同时更改两者以产生抖动效果。如果您希望旋转更改 Modifier.graphicsLayer 的rotationZ

 @Composable
private fun ShakeAnimationSamples() {
    Column(modifier = Modifier
        .fillMaxSize()
        .padding(10.dp)) {

        var enabled by remember {
            mutableStateOf(false)
        }
        val scale by animateFloatAsState(
            targetValue = if (enabled) .9f else 1f,
            animationSpec = repeatable(
                iterations = 5,
                animation = tween(durationMillis = 50, easing = LinearEasing),
                repeatMode = RepeatMode.Reverse
            ),
            finishedListener = {
                enabled = false
            }
        )

        val infiniteTransition = rememberInfiniteTransition()
        val scaleInfinite by infiniteTransition.animateFloat(
            initialValue = 1f,
            targetValue = .85f,
            animationSpec = infiniteRepeatable(
                animation = tween(30, easing = LinearEasing),
                repeatMode = RepeatMode.Reverse
            )
        )

        val rotation by infiniteTransition.animateFloat(
            initialValue = -10f,
            targetValue = 10f,
            animationSpec = infiniteRepeatable(
                animation = tween(30, easing = LinearEasing),
                repeatMode = RepeatMode.Reverse
            )
        )

        Icon(
            imageVector = Icons.Default.NotificationsActive,
            contentDescription = null,
            tint = Color.White,
            modifier = Modifier
                .graphicsLayer {
                    scaleX = if (enabled) scale else 1f
                    scaleY = if (enabled) scale else 1f
                }
                .background(Color.Red, CircleShape)
                .size(50.dp)
                .padding(10.dp)
        )

        Icon(
            imageVector = Icons.Default.NotificationsActive,
            contentDescription = null,
            tint = Color.White,
            modifier = Modifier
                .graphicsLayer {
                    scaleX = scaleInfinite
                    scaleY = scaleInfinite
                    rotationZ = rotation
                }
                .background(Color.Red, CircleShape)
                .size(50.dp)
                .padding(10.dp)
        )



        Button(onClick = { enabled = !enabled }) {
            Text("Animation enabled: $enabled")
        }

    }
}

您也可以将其作为修改器

fun Modifier.shake(enabled: Boolean) = composed(

    factory = {
        
        val scale by animateFloatAsState(
            targetValue = if (enabled) .9f else 1f,
            animationSpec = repeatable(
                iterations = 5,
                animation = tween(durationMillis = 50, easing = LinearEasing),
                repeatMode = RepeatMode.Reverse
            )
        )

        Modifier.graphicsLayer {
            scaleX = if (enabled) scale else 1f
            scaleY = if (enabled) scale else 1f
        }
    },
    inspectorInfo = debugInspectorInfo {
        name = "shake"
        properties["enabled"] = enabled
    }
)

Usage

Icon(
    imageVector = Icons.Default.NotificationsActive,
    contentDescription = null,
    tint = Color.White,
    modifier = Modifier
        .shake(enabled)
        .background(Color.Red, CircleShape)
        .size(50.dp)
        .padding(10.dp)
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android Compose 创建摇动动画 的相关文章

随机推荐

  • Go 中的 getpasswd 功能?

    情况 我想从以下位置获取密码条目stdin安慰 不回显用户输入的内容 有没有类似的东西getpasswdGo 中的功能 我尝试过的 我尝试使用syscall Read 但它与键入的内容相呼应 以下是其中之一最好的方法完成它 首先得到term
  • MPMoviePlayerController 音频显示“完成”按钮

    我使用 MPMoviePlayerController 来播放音频流 我的代码遵循以下示例 http iosdevelopertips com video getting mpmovieplayercontroller to coopera
  • 如何使用 Node.js 将文件从一台服务器传输到另一台服务器

    如果在其他地方问过这个问题 我很抱歉 但我找不到合适的解决方案来解决这个令人烦恼的问题 所以这就是我的情况 我有一个 node js 脚本 它从头开始创建一个 Excel 文档 一切都按预期工作 但是 我无法将这个新创建的文件保存到另一个运
  • onBackPressed 将数据发送到父活动[重复]

    这个问题在这里已经有答案了 有没有办法在按下后退时将更新的数据发送到父活动 我想更新捆绑包中的数据 但我不知道如何访问它 例如 我有一个打开图像查看器的画廊活动 假设用户滚动浏览十几张图像 然后返回到图库 理想的做法是使用他们最后查看的图像
  • Rust 有没有办法用索引折叠?

    在 Ruby 中 如果我有一个数组a 1 2 3 4 5 我想得到每个元素乘以它的索引的总和 a each with index inject 0 s i j s i j 在 Rust 中是否有一种惯用的方法可以做同样的事情 到目前为止 我
  • 使用 nghandsontable 访问 Handsontable 方法/属性

    我在用着ngHandson表 https github com handsontable ngHandsontable角度指令手动表 http handsontable com 我成功地显示了数据 但我正在努力访问修改后的行 以便将数据发送
  • 将对象转换为 类型

    我正在实现一个类的 List 接口 该类将数据存储在
  • iOS 自定义地图、地理位置、地图绘制等

    下一张图片取自 www Trimaps com 我希望这里允许使用图片 如果不允许 请告诉我 我会立即删除 这些图像完美地解释了我想要实现的目标 我拥有所需的所有数据 所需区域 4 个角的纬度 经度 以十进制值表示 来自 Google 地图
  • Clojure:在嵌套哈希图中搜索 val 并返回包含该 val 的键序列的函数

    假设我们有一个包含嵌套数据结构的集合 def coll a aa b d dd e f h hh i ii g gg c cc 我想创建一个函数 在嵌套结构中的任何位置搜索 val 并返回包含该 val 的键序列 search parent
  • 使用 Bootstrap ScrollSpy 将 div 折叠到固定的侧边栏

    我将此代码作为页面的布局 span9 div 包含应应用滚动间谍的部分 每个部分都是一组包含实际内容的可折叠 div span3 div 是固定的侧边栏 必须使用滚动间谍突出显示正确的项目 div class span3 module si
  • iOS 配置文件在 6 天后过期

    我是 iOS 开发新手 因为我目前只为 Android 开发 我遇到了一个问题 我一直在寻找可能的解决方案 我想做一个个人 iOS 应用程序 比如个人笔记应用程序或个人提醒应用程序等 我成功了 唯一的问题是配置文件仅持续 6 天 我认为 并
  • iPhone 5屏幕尺寸VS CSS媒体查询[重复]

    这个问题在这里已经有答案了 可能的重复 iPhone 5 CSS 媒体查询 https stackoverflow com questions 12539697 iphone 5 css media query iPhone 5 技术规格规
  • 如何生成一个随机数,然后将其显示在屏幕上?

    好吧 我对 Android 相当陌生 但我已经设法自学了基础知识 我正在制作一个应用程序 您按下一个按钮 就会打开一个新屏幕 它会显示一个随机生成的数字 唯一的问题是我不知道如何生成并显示随机数 我已经在网络上搜索了很长时间 只找到了很少的
  • UITextView 偏移文本的方式与 UILabel 不同

    我在用UILabel and UI文本视图并且它们以不同的方式呈现文本 看起来UI文本视图将文本偏移 4 下面是一个例子 其中顶部是UILabel下面是UI文本视图 他们都使用相同的字体 这里有两个例子 一个是自定义的OpenSans字体和
  • 在 iOS16 中以编程方式推送 NavigationLink

    在以前的 iOS 版本中 我以编程方式推送了一个 NavigationLink NavigationLink isActive searched destination SearchView originalSearchPhrase sea
  • 是否可以设置 html5 音频标签的样式?

    我还没有找到任何关于如何做到这一点的资源 像改变播放器颜色这样简单的事情就很好了 是的 您可以隐藏内置浏览器 UI 通过删除controls属性来自audio 而是构建您自己的界面并使用 Javascript 控制播放 source htt
  • Angular 如何根据路线更改导航菜单标题

    我正在使用 Angular 4 在当前项目中开发仪表板布局 当用户在应用程序的不同部分之间导航时 我需要更新导航菜单标题标题以反映应用程序的当前部分 例如 当用户访问设置时 页面标题 应更改为 设置 该项目基于 net core 2 Ang
  • 突变残基和位置的数字编码

    我正在编写一个 python 程序 它必须计算突变残基和位置的数字编码一组字符串 这些字符串是蛋白质序列 这些序列存储在 fasta 格式文件中 每个蛋白质序列用逗号分隔 不同蛋白质的序列长度可能不同 在此我试图找到以下位置和序列 变异了
  • wordpress 在functions.php第5行中的非对象上调用成员函数add_section()

    嘿 我对 php 和 WordPress 开发有点陌生 我只是在尝试 WordPress 的工作原理以及主题的工作原理 现在我已经尝试多次查找此内容但没有帮助 总是有一些不同的东西 对那些人有用的东西 对我不起作用 这是代码
  • Android Compose 创建摇动动画

    我正在尝试在 Jetpack Compose 中制作形状的晃动动画 我想在用户输入无效的 Pin 码时使用此动画来显示错误 但我能找到的只是滑入 滑出动画和一些缩放动画 我有什么想法可以做到这一点吗 Update 在 Thracian 回答