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

Android Compose Activity 页面跳转动画详解

下面我将全面详细地介绍在 Compose 中实现 Activity 跳转动画的各种方法,包括基础实现、高级技巧和最佳实践。

一、基础 Activity 过渡动画

1. overridePendingTransition 传统方式

这是最基础且兼容性最好的方法,适用于所有 Android 版本。

实现步骤:

  1. 创建动画资源文件 (res/anim/)
<!-- slide_in_right.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:duration="300"android:fromXDelta="100%p"android:toXDelta="0%p"android:interpolator="@android:anim/decelerate_interpolator"/>
</set><!-- slide_out_left.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:duration="300"android:fromXDelta="0%p"android:toXDelta="-100%p"android:interpolator="@android:anim/decelerate_interpolator"/>
</set><!-- fade_in.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android"><alphaandroid:duration="300"android:fromAlpha="0.0"android:toAlpha="1.0"android:interpolator="@android:anim/accelerate_interpolator"/>
</set>
  1. 在 Compose 中触发跳转
@Composable
fun FirstScreen() {val context = LocalContext.currentButton(onClick = {context.startActivity(Intent(context, SecondActivity::class.java))(context as Activity).overridePendingTransition(R.anim.slide_in_right, R.anim.fade_out)}) {Text("跳转到第二个Activity")}
}
  1. 在目标 Activity 中设置返回动画
class SecondActivity : ComponentActivity() {override fun finish() {super.finish()overridePendingTransition(R.anim.fade_in,R.anim.slide_out_left)}
}

2. 进阶动画组合

你可以组合多种动画效果:

<!-- slide_and_fade_in.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:duration="400"android:fromXDelta="20%"android:toXDelta="0%"android:interpolator="@android:anim/decelerate_interpolator"/><alphaandroid:duration="400"android:fromAlpha="0.0"android:toAlpha="1.0"android:interpolator="@android:anim/accelerate_interpolator"/><scaleandroid:duration="400"android:fromXScale="0.9"android:toXScale="1.0"android:fromYScale="0.9"android:toYScale="1.0"android:pivotX="50%"android:pivotY="50%"/>
</set>

二、共享元素过渡 (Android 5.0+)

1. 基本实现

共享元素过渡可以创建更流畅的视觉体验。

步骤1:在布局中定义过渡名称

@Composable
fun FirstScreen() {val context = LocalContext.currentval imageView = LocalView.currentColumn {Image(painter = rememberImagePainter(data = "https://example.com/image.jpg"),contentDescription = "共享图片",modifier = Modifier.size(200.dp).clickable {val intent = Intent(context, DetailActivity::class.java)val options = ActivityOptionsCompat.makeSceneTransitionAnimation(context as Activity,imageView,"shared_image" // 必须与DetailActivity中的名称一致)context.startActivity(intent, options.toBundle())}.composed {// 设置过渡名称ViewCompat.setTransitionName(imageView, "shared_image")Modifier})}
}

步骤2:在目标Activity中设置相同的过渡名称

class DetailActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {val imageView = LocalView.currentColumn {Image(painter = rememberImagePainter(data = "https://example.com/image.jpg"),contentDescription = "详情图片",modifier = Modifier.fillMaxWidth().aspectRatio(1f).composed {ViewCompat.setTransitionName(imageView, "shared_image")Modifier})}}}
}

2. 多个共享元素

// 启动Activity时
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,Pair(view1, "transition_title"),Pair(view2, "transition_image"),Pair(view3, "transition_bg")
)
startActivity(intent, options.toBundle())

三、高级过渡动画技巧

1. 使用 Material Motion 规范

Google 推荐的 Material Motion 过渡模式:

// 在styles.xml中定义主题继承
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight"><item name="android:windowActivityTransitions">true</item><item name="android:windowEnterTransition">@transition/explode</item><item name="android:windowExitTransition">@transition/explode</item><item name="android:windowSharedElementEnterTransition">@transition/change_image_transform</item><item name="android:windowSharedElementExitTransition">@transition/change_image_transform</item>
</style>// 过渡资源文件
<!-- change_image_transform.xml -->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"><changeImageTransform/><changeBounds/><changeTransform/>
</transitionSet>

2. 延迟共享元素过渡

有时需要等待数据加载完成再开始过渡:

class DetailActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 延迟过渡直到数据加载完成postponeEnterTransition()setContent {val imageView = LocalView.currentLaunchedEffect(Unit) {// 模拟数据加载delay(1000)// 开始过渡动画startPostponedEnterTransition()}// 界面内容...}}
}

四、常见问题解决方案

1. 状态栏和导航栏过渡

// 在主题中添加
<item name="android:windowSharedElementsUseOverlay">false</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>

2. 修复共享元素位置问题

// 在Compose中使用Modifier.clipToBounds()
Image(// ...modifier = Modifier.clipToBounds()
)

3. 自定义共享元素过渡

// 自定义SharedElementCallback
setExitSharedElementCallback(object : SharedElementCallback() {override fun onMapSharedElements(names: MutableList<String>,sharedElements: MutableMap<String, View>) {// 自定义映射逻辑}
})

五、性能优化建议

  1. 简化动画:避免过于复杂的动画效果
  2. 使用硬件加速:确保在manifest中启用了硬件加速
  3. 优化图片:共享元素中的图片应适当压缩
  4. 测试低端设备:确保动画在中低端设备上也能流畅运行
  5. 提供回退方案:为API<21的设备提供简单动画或直接跳转

六、完整示例代码

MainActivity.kt

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {MyAppTheme {FirstScreen()}}}
}@Composable
fun FirstScreen() {val context = LocalContext.currentval imageView = LocalView.currentColumn(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally) {// 简单跳转按钮Button(onClick = {context.startActivity(Intent(context, SimpleTransitionActivity::class.java))(context as Activity).overridePendingTransition(R.anim.slide_up,R.anim.stay)}) {Text("简单过渡效果")}Spacer(modifier = Modifier.height(16.dp))// 共享元素跳转Image(painter = rememberImagePainter(data = R.drawable.sample_image),contentDescription = "共享图片",modifier = Modifier.size(200.dp).clip(RoundedCornerShape(8.dp)).clickable {val intent = Intent(context, SharedElementActivity::class.java)val options = ActivityOptionsCompat.makeSceneTransitionAnimation(context as Activity,imageView,"shared_image")context.startActivity(intent, options.toBundle())}.composed {ViewCompat.setTransitionName(imageView, "shared_image")Modifier})}
}

SharedElementActivity.kt

class SharedElementActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)Window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)setContent {MyAppTheme {val imageView = LocalView.currentColumn(modifier = Modifier.fillMaxSize()) {Image(painter = rememberImagePainter(data = R.drawable.sample_image),contentDescription = "详情图片",modifier = Modifier.fillMaxWidth().aspectRatio(1f).padding(16.dp).clip(RoundedCornerShape(12.dp)).composed {ViewCompat.setTransitionName(imageView, "shared_image")Modifier})Spacer(modifier = Modifier.height(16.dp))Button(onClick = { finishAfterTransition() }) {Text("返回")}}}}}
}

通过以上方法,你可以在 Compose 项目中实现各种精美的 Activity 跳转动画效果。根据项目需求选择合适的方式,并注意测试不同设备和 Android 版本的兼容性。

http://www.xdnf.cn/news/1441.html

相关文章:

  • 【Leetcode 每日一题】2176. 统计数组中相等且可以被整除的数对
  • ubuntu磁盘挂载
  • MySQL GTID集合运算函数总结
  • e实例性能测评:Intel Xeon Platinum处理器,经济型入门级服务器
  • Java设计开发商城抢票功能
  • Sql刷题日志(day3)
  • 代码随想录算法训练营第二十天
  • 关于C语言的模拟物理模型
  • vue3 el-dialog新增弹窗,不希望一进去就校验名称没有填写
  • SQL刷题记录贴
  • Oracle测试题目及笔记(单选)
  • 赛灵思 XCVU3P‑2FFVC1517I XilinxFPGA Virtex UltraScale+
  • AI在市场营销分析中的核心应用及价值,分场景详细说明
  • 【创新实训个人博客】前端实现
  • 【运维学习】lvs + keepalived + 主从dns 项目搭建
  • Valgrind的使用复习
  • 更换 CentOS 7.9 的系统源
  • 【软考-系统架构设计师】ATAM方法及效用树
  • 【python】pyCharm常用快捷键使用-(2)
  • C++入门基础:命名空间,缺省参数,函数重载,输入输出
  • blender 录课键位显示插件(图文傻瓜式安装)
  • .net core 项目快速接入Coze智能体-开箱即用-全局说明
  • 数据结构之BFS广度优先算法(腐烂的苹果)
  • ARINC818-1协议
  • visual Studio+Qt插件检查内存泄漏
  • Azure 私有端点和存储帐户用例
  • 基于springboot医药连锁店管理系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 【论文精读】COLMAP-Free 3D Gaussian Splatting
  • vue入门:路由 router
  • [GESP202409 二级] 小杨的 N 字矩阵 题解