如何通过将源 activity 中的元素移动到目标位置来为过渡中的共享元素设置动画?
How to animate shared element in transition by moving the element in source activity to dest position?
我在从 activity A 到 activity B 的过渡中有一个共享元素。但是,A 中的共享元素使用了 TransitionDrawable,有时我想触发可绘制,使用 startTransition
,作为过渡的一部分。 (B中的共享元素看起来像是过渡的结束状态。)
共享元素转换文档指出,实现将 B 中的共享元素移动到 A 中共享元素的屏幕位置。然后它将运行共享元素进入转换。
是否可以将 A 中的元素移动到 B 元素的位置(让我 运行 startTransition 通过共享元素回调)而不是其他方式? P.S.: 我知道共享元素退出转换,但我认为这对我没有帮助,因为在 activity 转换开始之前总是 运行s,我看不到一种改变它的方法,在文档中。
我通过 SharedElementCallback 利用共享元素快照。虽然它总体上相当复杂,但这是我的代码部分,它处理拍摄快照并使用快照作为底层重新创建 TransitionDrawable。
override fun onSharedElementEnd(sharedElementNames: MutableList<String>,
sharedElements: MutableList<View>,
sharedElementSnapshots: MutableList<View>?) {
if (sharedElements.size < 1)
return
val shElem = sharedElements[0]
if (shElem !is ImageView)
return
mainPhoto = shElem
if (mainPhoto!!.drawable !is TransitionDrawable) {
val layers = arrayOf(sharedElementSnapshots!![0].background, mainPhoto!!.drawable)
if (exiting)
layers.reverse()
val transDrwbl = android.graphics.drawable.TransitionDrawable(layers)
mainPhoto!!.setImageDrawable(transDrwbl)
} else
needToUseReverse = true
}
/**
* I'm copying these from v21 SharedElementCallback.java because, while the
* new functionality in v24 (v23?) seems nice, I don't want something unexpected
* to happen on newer versions
*/
override fun onCaptureSharedElementSnapshot(sharedElement: View, viewToGlobalMatrix: Matrix,
screenBounds: RectF): Parcelable {
val mTempMatrix = Matrix(viewToGlobalMatrix)
val transitionUtils = Class.forName("android.transition.TransitionUtils")
val createViewBitmap = transitionUtils.getDeclaredMethod("createViewBitmap", View::class.java, Matrix::class.java, RectF::class.java)
val pcbl = createViewBitmap.invoke(null, sharedElement, mTempMatrix, screenBounds) as Parcelable
return pcbl
}
override fun onMapSharedElements(names: MutableList<String>, sharedElements: MutableMap<String, View>) {
for (key in sharedElements.keys.toList())
if (key != currentSharedElementName)
sharedElements.remove(key)
}
override fun onCreateSnapshotView(context: Context, snapshot: Parcelable): View? {
var view: View? = null
if (snapshot is Bitmap) {
view = View(context)
val resources = context.resources
view.background = BitmapDrawable(resources, snapshot)
}
return view
}
我在从 activity A 到 activity B 的过渡中有一个共享元素。但是,A 中的共享元素使用了 TransitionDrawable,有时我想触发可绘制,使用 startTransition
,作为过渡的一部分。 (B中的共享元素看起来像是过渡的结束状态。)
共享元素转换文档指出,实现将 B 中的共享元素移动到 A 中共享元素的屏幕位置。然后它将运行共享元素进入转换。
是否可以将 A 中的元素移动到 B 元素的位置(让我 运行 startTransition 通过共享元素回调)而不是其他方式? P.S.: 我知道共享元素退出转换,但我认为这对我没有帮助,因为在 activity 转换开始之前总是 运行s,我看不到一种改变它的方法,在文档中。
我通过 SharedElementCallback 利用共享元素快照。虽然它总体上相当复杂,但这是我的代码部分,它处理拍摄快照并使用快照作为底层重新创建 TransitionDrawable。
override fun onSharedElementEnd(sharedElementNames: MutableList<String>,
sharedElements: MutableList<View>,
sharedElementSnapshots: MutableList<View>?) {
if (sharedElements.size < 1)
return
val shElem = sharedElements[0]
if (shElem !is ImageView)
return
mainPhoto = shElem
if (mainPhoto!!.drawable !is TransitionDrawable) {
val layers = arrayOf(sharedElementSnapshots!![0].background, mainPhoto!!.drawable)
if (exiting)
layers.reverse()
val transDrwbl = android.graphics.drawable.TransitionDrawable(layers)
mainPhoto!!.setImageDrawable(transDrwbl)
} else
needToUseReverse = true
}
/**
* I'm copying these from v21 SharedElementCallback.java because, while the
* new functionality in v24 (v23?) seems nice, I don't want something unexpected
* to happen on newer versions
*/
override fun onCaptureSharedElementSnapshot(sharedElement: View, viewToGlobalMatrix: Matrix,
screenBounds: RectF): Parcelable {
val mTempMatrix = Matrix(viewToGlobalMatrix)
val transitionUtils = Class.forName("android.transition.TransitionUtils")
val createViewBitmap = transitionUtils.getDeclaredMethod("createViewBitmap", View::class.java, Matrix::class.java, RectF::class.java)
val pcbl = createViewBitmap.invoke(null, sharedElement, mTempMatrix, screenBounds) as Parcelable
return pcbl
}
override fun onMapSharedElements(names: MutableList<String>, sharedElements: MutableMap<String, View>) {
for (key in sharedElements.keys.toList())
if (key != currentSharedElementName)
sharedElements.remove(key)
}
override fun onCreateSnapshotView(context: Context, snapshot: Parcelable): View? {
var view: View? = null
if (snapshot is Bitmap) {
view = View(context)
val resources = context.resources
view.background = BitmapDrawable(resources, snapshot)
}
return view
}