Android使用Glide实现Shared element transition二次触发动画异常如何解决
Android Glide 共享元素过渡异常修复方案
异常表现
- 首次点击列表ImageView跳转到大图页,共享元素动画正常,第二次点击时动画从右下角开始展开
- 从大图页返回列表页时,动画从左上角开始收缩回原位置,无图片压缩过渡效果
- 异常效果演示:

原过渡配置
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000"> <changeTransform /> <changeClipBounds /> <changeBounds /> <changeImageTransform /> </transitionSet>
修复方案
1. 解决第二次点击动画从右下角展开问题
该异常是因为首次跳转返回后,列表页ImageView的矩阵、缩放类型状态被修改,共享元素动画捕获的起始尺寸、位置参数错误导致,按以下步骤修复:
- 列表页
onResume生命周期中重置共享元素ImageView状态
override fun onResume() { super.onResume() // 替换为你列表页ImageView原本使用的ScaleType,如CENTER_CROP sharedImageView.scaleType = ImageView.ScaleType.CENTER_CROP sharedImageView.clearAnimation() // 重置Glide加载状态,重新加载缩略图保证参数一致 Glide.with(this).clear(sharedImageView) Glide.with(this).load(缩略图地址).into(sharedImageView) }
- 跳转前暂停共享元素过渡,等待大图页图片加载完成后再启动动画
跳转启动逻辑:
val transitionOptions = ActivityOptions.makeSceneTransitionAnimation( this, sharedImageView, // 两个页面共享元素的transitionName必须完全一致 "shared_image_transition_name" ) // 先暂停过渡,等大图加载完成再执行 postponeEnterTransition() startActivity(跳转Intent, transitionOptions.toBundle())
大图页Glide加载逻辑新增监听:
Glide.with(this) .load(原图地址) .listener(object : RequestListener<Drawable> { override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean { // 加载失败也启动过渡,避免页面卡住 startPostponedEnterTransition() return false } override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean { // 图片加载完成后启动过渡动画 startPostponedEnterTransition() return false } }) .into(bigImageView)
2. 解决返回动画从左上角收缩问题
该异常是因为过渡集的执行顺序错误,changeImageTransform需要优先执行才能正确捕获图片的缩放变换参数,同时需要适配返回过渡的暂停逻辑:
- 修改过渡集配置,调整标签顺序、添加插值器优化效果:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:interpolator="@android:interpolator/fast_out_slow_in"> <!-- changeImageTransform必须放在最前面 --> <changeImageTransform /> <changeTransform /> <changeClipBounds /> <changeBounds /> </transitionSet>
- 大图页添加返回过渡适配逻辑:
override fun onBackPressed() { supportFinishAfterTransition() postponeEnterTransition() super.onBackPressed() }
注意事项
- 列表页和大图页的共享元素ImageView的
adjustViewBounds属性需要保持一致,避免尺寸计算偏差 - 两个页面的共享元素
transitionName必须完全相同,不要出现拼写错误
内容的提问来源于stack exchange,提问作者jk multi
相关产品推荐
相关产品推荐

