我有图像适配器,其中每个项目都是用户图像,单击它会打开一个包含所选用户图像的新 Activity ,因此我将图像标记为共享元素并使用 Activity 转换。
我对第二个 Activity 执行的部分操作会影响所有用户,因此适配器调用 notifyDataSetChanged
并将位置重置为列表顶部。
发生这种情况时,它会弄乱返回动画,当我关闭第二个 Activity 并返回到列表时,其中的数据已更改,因此图像会动画到错误的单元格。
我有两个问题:
- 如何将动画重新映射到正确的单元格?所有的单元格都有相同的共享 id...
- 如果我的用户不再出现在列表中,我该如何用不同的动画替换返回动画?
最佳答案
What can I do to remap the animation to the right cell? All the cells got the same shared id.
在第一个 Activity 中,您应该有一些键来指定启动第二个 Activity 的项目。假设您有一个 Map
独特的userId
s 和 User
s,即 Map<Integer, User>
.
- 启动第二个 Activity 时传递此
User
map 中的键,假设它是42
. (在 map42 -> John Doe
中,您正在为John Doe
启动第二个 Activity )。 setExitSharedElementCallback()
在第一个 Activity 中覆盖onMapSharedElements()
.override fun onMapSharedElements(names: MutableList<String>?, sharedElements: MutableMap<String, View>?) { // we will implement this in step 6 }
覆盖
onActivityReenter()
在第一个 Activity 中并使用supportPostponeEnterTransition()
推迟过渡,以便在我们执行某些操作之前不显示过渡(例如,我们想要滚动列表以显示该项目)。- 在
onActivityReenter()
保存Bundle
你已经通过Intent
从第二个 Activity 中通过了(我们将在第 7 步中看到)。 - 在
onActivityReenter()
中推迟过渡之后根据您添加到此包中的信息对 UI 进行一些更改。特别是,在我们的例子中,这个包将包括原始的Integer
User
的关键启动第二个 Activity 。您可能会找到User
的当前位置按此键在列表中,然后滚动RecyclerView
到那个新位置。使此项目可见后,您可以按下触发器并让系统通过supportStartPostponedEnterTransition()
开始转换。 . 在
SharedElementCallback::onMapSharedElements()
检查天气Bundle
您在步骤 4 中保存的是否为空。如果它不为空,则意味着您在第二个 Activity 中做了一些事情并且您希望重新映射共享元素。这意味着你必须做这样的事情: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 } }
在第二个 Activity 中覆盖
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() }
In case that my user is no longer visible on the list, how can I replace the return animation with different animation?
您可以使其可见(例如,通过滚动 RecyclerView
太多,以至于您的 View 变得可见),或者您可以通过清除 names
来删除步骤 6 中的共享元素过渡。和 sharedElements
并且不向其中添加任何东西。
我希望你已经了解了它的工作原理,尽管它看起来有点困惑。但作为对您的帮助,我可以分享我编写的应用程序中的一些代码:
关于java - 数据更改时的 Activity 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42509345/