如何实现两个Activity之间的Motion Layout过渡效果
两个Activity间实现MotionLayout过渡效果的实现步骤
MotionLayout本身仅支持单个页面内的View树动画,要跨Activity实现过渡需要配合Android的共享元素过渡机制,具体实现步骤如下:
- 配置共享元素标识
给两个Activity布局中需要参与过渡的对应View设置完全一致的android:transitionName属性,作为共享元素的匹配标记。 - 编写MotionScene过渡规则
将第二个Activity的根布局替换为MotionLayout,编写对应的MotionScene配置文件,定义共享元素从入场初始状态到页面最终状态的所有属性变化规则(大小、位置、透明度、圆角、颜色等都可自定义)。 - 替换页面启动逻辑
在第一个Activity启动第二个Activity时,构造共享元素参数启动页面:val options = ActivityOptionsCompat.makeSceneTransitionAnimation( this@FirstActivity, sharedView, // 第一个页面的共享元素控件 "shared_transition_name" // 和之前设置的transitionName一致 ) startActivity(Intent(this@FirstActivity, SecondActivity::class.java), options.toBundle()) - 绑定MotionLayout动画触发逻辑
在第二个Activity的onCreate方法中添加共享元素回调,同步触发MotionLayout的过渡动画:setEnterSharedElementCallback(object : SharedElementCallback() { override fun onSharedElementStart( sharedElementNames: MutableList<String>?, sharedElements: MutableList<View>?, sharedElementSnapshots: MutableList<View>? ) { super.onSharedElementStart(sharedElementNames, sharedElements, sharedElementSnapshots) // 重置MotionLayout到起始状态 motionLayout.progress = 0f } override fun onSharedElementEnd( sharedElementNames: MutableList<String>?, sharedElements: MutableList<View>?, sharedElementSnapshots: MutableList<View>? ) { super.onSharedElementEnd(sharedElementNames, sharedElements, sharedElementSnapshots) // 启动MotionLayout过渡,时长和共享元素过渡时长保持一致即可 motionLayout.transitionToEnd(300) } }) - 解决动画冲突
在第二个Activity的主题配置中添加以下配置,关闭系统自带的共享元素过渡动画,避免和MotionLayout动画冲突:<item name="android:windowSharedElementsEnterTransition">@null</item> <item name="android:windowSharedElementsExitTransition">@null</item>
如需实现返回时的反向过渡,在第二个页面关闭时调用
finishAfterTransition()替代普通的finish()方法,同时在MotionScene中配置反向过渡规则即可。
如果你不需要指定共享元素,只想做整页的MotionLayout过渡效果,可以在启动第二个Activity前将第一个页面的截图传入第二个Activity,作为MotionLayout的起始层,入场时触发过渡后隐藏截图层即可实现连贯的跨页动画。
内容的提问来源于stack exchange,提问作者Yogesh
相关产品推荐
相关产品推荐

