我有图像适配器,其中每个项目都是用户图像,点击它时会打开一个包含所选用户图像的新活动,因此我将图像标记为共享元素并使用活动过渡。
我对第二个活动执行的部分操作会影响所有用户,因此适配器会调用notifyDataSetChanged
并将位置重置为列表顶部。
当发生这种情况时,它会弄乱返回动画,当我关闭第二个活动并返回列表时,其中的数据已被更改,因此图像会被动画化为错误的单元格。
我有两个问题:
答案 0 :(得分:1)
如何将动画重新映射到正确的单元格?所有单元格都有相同的共享ID。
在第一个活动中,您应该有一些键来指定启动第二个活动的项目。假设您有Map
个唯一的userId
和User
s,即Map<Integer, User>
。
User
的密钥,假设它是42
。 (在地图42 -> John Doe
中,您要为John Doe
启动第二项活动。 setExitSharedElementCallback()
并覆盖onMapSharedElements()
。
override fun onMapSharedElements(names: MutableList<String>?,
sharedElements: MutableMap<String, View>?) {
// we will implement this in step 6
}
在第一个活动中覆盖onActivityReenter()
并使用supportPostponeEnterTransition()
推迟转换,以便在我们做出一些操作之前不显示转换(例如,我们要滚动列表以显示项目)。
onActivityReenter()
中保存您通过Bundle
从第二项活动传递的Intent
(我们将在步骤7中看到)。onActivityReenter()
中推迟转换后,根据您添加到此捆绑包的信息对UI执行一些更改。特别是,在我们的情况下,此捆绑包将包含启动第二个活动的Integer
的原始User
密钥。您可以通过此键找到列表中User
的当前位置,并将RecyclerView
滚动到该新位置。使该项目可见后,您可以按下触发器,让系统按supportStartPostponedEnterTransition()
开始转换。在SharedElementCallback::onMapSharedElements()
检查天气中,您在步骤4中保存的Bundle
为空或不是。如果它不为null,那么这意味着您已在第二个活动中创建了一些内容,并且您希望重新发送共享元素。这意味着您必须执行以下操作:
override fun onMapSharedElements(names: MutableList<String>?,
sharedElements: MutableMap<String, View>?) {
// `reenterBundle` is the `Bundle` you have saved in step 3
if (null != reenterBundle
&& reenterBundle!!.containsKey("KEY_FROM_ACTIVITY_2")
&& null != view) {
val key = reenterBundle!!.getInt("KEY_FROM_ACTIVITY_2");
val newSharedElement = ... // find corresponding view with the `key`
val newTransitionName = ... // transition name of the view
// clear previous mapping and add new one
names?.clear()
names?.add(newTransitionName)
sharedElements?.clear()
sharedElements?.put(newTransitionName, newSharedElement)
reenterBundle = null
} else {
// The activity is exiting
}
}
在第二个活动覆盖finishAfterTransition()
:
override fun finishAfterTransition() {
val data = Intent()
data.putExtra("KEY_FROM_ACTIVITY_2", 42) // `42` is the original position that we passed to this activity via Intent when launching it
setResult(RESULT_OK, data)
super.finishAfterTransition()
}
如果我的用户在列表中不再可见,我该如何用不同的动画替换返回动画?
您可以将其显示为可见(例如,通过滚动RecyclerView
以及您的视图变得可见),或者您可以通过清除names
和{{}来删除步骤6中的共享元素转换1}}而不是在其中添加任何内容。
我希望你已经学会了它的工作原理,虽然看起来有些混乱。但作为对你的帮助,我可以从我写的应用程序中分享一些代码: