java - custom - android transition使用



数据更改时的活动转换 (1)

我得到了图像适配器,其中每个项目是用户图像,点击后,它会打开一个新的活动与选定的用户图像,所以我把图像标记为共享元素和使用活动转换。

我对第二个活动执行的部分操作会影响所有用户,因此适配器将调用notifyDataSetChanged并将位置重置为列表顶部。

当发生这种情况时,它会搞乱返回动画,当我关闭第二个活动并返回到列表中的数据已更改,以便图像动画到错误的单元格。

我有两个问题:

  1. 我能做些什么来将动画重新映射到正确的单元格? 所有的单元格都有相同的共享ID ...
  2. 如果我的用户不再在列表中可见,我怎样才能用不同的动画替换返回动画?

Answer #1

我能做些什么来将动画重新映射到正确的单元格? 所有的单元格都有相同的共享ID。

在第一个活动中,您应该有一些指定启动第二个活动的项目的键。 假设你有一个唯一的userIdUserMap<Integer, User> ,即Map<Integer, User>

  1. 当你启动第二个活动时,在地图中传递这个User的密钥,假设它是42 。 (在地图42 -> John Doe ,你正在为John Doe发起第二次活动)。
  2. 在第一个活动中设置setExitSharedElementCallback() ,并重写onMapSharedElements()

    override fun onMapSharedElements(names: MutableList<String>?,
                                 sharedElements: MutableMap<String, View>?) {
        // we will implement this in step 6                            
    }
  3. 在第一个活动中覆盖onActivityReenter() ,并使用supportPostponeEnterTransition()推迟转换,以便在我们做出一些动作(例如,我们想要滚动列表以显示项目)之前不显示转换。

  4. onActivityReenter()保存你通过Intent从第二个活动传递过来的Bundle (我们将在第七步中看到)。
  5. onActivityReenter()推迟转换之后,根据添加到此捆绑包的信息对UI进行一些更改。 特别是,在我们的情况下,这个包将包含启动第二个活动的User的原始Integer键。 您可以通过此键在列表中找到User当前位置,并将RecyclerView滚动到新的位置。 使这个项目可见之后,您可以按下触发器并让系统通过supportStartPostponedEnterTransition()启动转换。
  6. SharedElementCallback::onMapSharedElements()检查天气,在步骤4中保存的Bundle是否为null。 如果不是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
        }                            
    }
  7. 在第二个活动覆盖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这么多,您的视图变得可见),或者你可以通过清除namessharedElements删除共享元素转换,并sharedElements names和共享元素,而不是添加任何东西。

我希望你已经学会了它的工作原理,虽然看起来有点乱。 但作为对你的帮助,我可以从我写的应用程序中分享一些代码:

MainActivity - MainPresenter

DetailActivity





activity-transition