Compose 5 个简短动画,让您的应用脱颖而出

5 quick animations to make your Compose app stand out

浏览 5 个快速动画,让您的应用在短短几分钟内生动起来。

1. AnimatedVisibility()

下面使用简单的 if 语句来显示或隐藏文本。

为了提升 UI 效果,将不断变化的可见状态包装在 AnimatedVisibility 组合中,使得文本的显示或隐藏带有动画效果。

kotlin 复制代码
@Composable
public fun AnimatedVisibility(
    visible: Boolean,
    modifier: Modifier = Modifier,
    enter: EnterTransition = fadeIn() + expandIn(),
    exit: ExitTransition = shrinkOut() + fadeOut(),
    label: String = "AnimatedVisibility",
    content: @Composable() AnimatedVisibilityScope.() -> Unit,
) {
    val transition = updateTransition(visible, label)
    AnimatedVisibilityImpl(transition, { it }, modifier, enter, exit, content = content)
}

AnimatedVisibility 还有一系列不同的自定义选项。

2. Modifier.animateContentSize()

通过更改 Text 在屏幕上绘制的最大行数,单击文本时切换展开状态,

我们可以使用 Modifier 轻松修复这种跳跃状态。只需要将 animateContentSize() 添加到 Modifier 链中,即可获得即时平滑的变化。

kotlin 复制代码
public fun Modifier.animateContentSize(
    animationSpec: FiniteAnimationSpec<IntSize> =
        spring(
            stiffness = Spring.StiffnessMediumLow,
            visibilityThreshold = IntSize.VisibilityThreshold,
        ),
    finishedListener: ((initialValue: IntSize, targetValue: IntSize) -> Unit)? = null,
): Modifier =
    this.clipToBounds() then
        SizeAnimationModifierElement(animationSpec, Alignment.TopStart, finishedListener)

如果想让动画变得更有弹性,可以更改 animateContentSize() 修饰符以接受动画规范。 大多数动画 API 都提供设置动画规范的功能,可以使用它来定义动画如何发生。

下面给动画添加弹簧规范,将刚度 stiffness 设置为低,并添加少量的弹跳 dampingRatio 为 DampingRatioLowBouncy。我们可以看到动画拥有了弹跳的效果。

3. AnimatedContent()

通过选择多 Tab 中的选项,来切换不同的组合内容。此时的内容切换十分生硬,内容之间没有任何的平滑过渡。

将切换内容代码包装在 AnimatedContent 组合中,提供将要转换到的目标状态。现在不同组合项之间的切换具有淡入淡出和相互缩放的效果,比之前好多了。

kotlin 复制代码
@Composable
public fun <S> AnimatedContent(
    targetState: S,
    modifier: Modifier = Modifier,
    transitionSpec: AnimatedContentTransitionScope<S>.() -> ContentTransform = {
        (fadeIn(animationSpec = tween(220, delayMillis = 90)) +
                scaleIn(initialScale = 0.92f, animationSpec = tween(220, delayMillis = 90)))
            .togetherWith(fadeOut(animationSpec = tween(90)))
    },
    contentAlignment: Alignment = Alignment.TopStart,
    label: String = "AnimatedContent",
    contentKey: (targetState: S) -> Any? = { it },
    content: @Composable() AnimatedContentScope.(targetState: S) -> Unit,
) {
    val transition = updateTransition(targetState = targetState, label = label)
    transition.AnimatedContent(
        modifier,
        transitionSpec,
        contentAlignment,
        contentKey,
        content = content,
    )
}

通过更改 AnimatedContent 的过渡规范,我们可以自定义屏幕上出现的的新可组合项如何进入屏幕以及旧可组合项如何退出屏幕。

使用 slideIntoContainer 将新内容向上滑动进入,使用 slideOutOfContainer 将旧内容向下滑动退出。我们还通过 animationSpec 设置动画的持续时间和缓动效果。

4. animateFloatAsState()

进度条计算进度并更新展示,这样的变化十分生硬,缺少平滑过渡。

使用 animateFloatAsState() 动态计算进度,使得进度条的变化产生动画效果。

kotlin 复制代码
@Composable
public fun animateFloatAsState(
    targetValue: Float,
    animationSpec: AnimationSpec<Float> = defaultAnimation,
    visibilityThreshold: Float = 0.01f,
    label: String = "FloatAnimation",
    finishedListener: ((Float) -> Unit)? = null,
): State<Float> {
    val resolvedAnimSpec =
        if (animationSpec === defaultAnimation) {
            remember(visibilityThreshold) { spring(visibilityThreshold = visibilityThreshold) }
        } else {
            animationSpec
        }
    return animateValueAsState(
        targetValue,
        Float.VectorConverter,
        resolvedAnimSpec,
        visibilityThreshold,
        label,
        finishedListener,
    )
}

5. rememberInfiniteTransition() with Custom DrawScope drawing

实现自定义彩虹边框,颜色围绕着图像轮廓旋转。这里需要使用无限执行的动画。

  • 使用 rememberInfiniteTransition() 创建一个无限动画 InfiniteTransition 声明为 infiniteTransition
kotlin 复制代码
@Composable
public fun rememberInfiniteTransition(label: String = "InfiniteTransition"): InfiniteTransition {
    val infiniteTransition = remember { InfiniteTransition(label) }
    infiniteTransition.run()
    return infiniteTransition
}
  • 调用 infiniteTransition.animateFloat() 创建一个动态变化的 State 声明为 rotationAnimation
kotlin 复制代码
@Composable
public fun InfiniteTransition.animateFloat(
    initialValue: Float,
    targetValue: Float,
    animationSpec: InfiniteRepeatableSpec<Float>,
    label: String = "FloatAnimation",
): State<Float> =
    animateValue(initialValue, targetValue, Float.VectorConverter, animationSpec, label)
  • 在 Image 的 Modifier.drawBehind{} 代码块中调用 rotate() 方法,参数 degrees 角度传入上一步声明的 rotationAnimation
kotlin 复制代码
/** Draw into a [Canvas] behind the modified content. */
fun Modifier.drawBehind(onDraw: DrawScope.() -> Unit) = this then DrawBehindElement(onDraw)

inline fun DrawScope.rotate(degrees: Float, pivot: Offset = center, block: DrawScope.() -> Unit) =
    withTransform({ rotate(degrees, pivot) }, block)
  • 如此在绘制彩虹边框背景的时候,边框会不停地围绕图像旋转。

infiniteRepeatable()

创建一个无限重复动画规格

kotlin 复制代码
@Stable
public fun <T> infiniteRepeatable(
    animation: DurationBasedAnimationSpec<T>,
    repeatMode: RepeatMode = RepeatMode.Restart,
    initialStartOffset: StartOffset = StartOffset(0),
): InfiniteRepeatableSpec<T> = InfiniteRepeatableSpec(animation, repeatMode, initialStartOffset)
相关推荐
游戏开发爱好者83 小时前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
王码码20353 小时前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥3 小时前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓3 小时前
[JDBC]元数据
android
独行soc3 小时前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能4 小时前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿4 小时前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc4 小时前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
王码码20355 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
2501_915106325 小时前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview