【问题标题】:Shared Element Transition is broken between three or more activities共享元素转换在三个或更多活动之间中断
【发布时间】:2019-12-06 14:18:22
【问题描述】:

问题

我想实现Activity A和B之间以及Activity B和C之间的共享元素过渡。

我所做的一切都是基于android transition documentation

之间没有问题:

  • A => B =>回到A

  • A => B 和 B => C => 回到 B

但如果我这样做:

  • A => B 和 B => C => 回到 B => 回到 A

最后一步不会有任何共享元素过渡(实际上不只是共享元素过渡,即使只有淡入淡出也可能丢失)。

我一直在到处寻找解决方案,但似乎每个人都只需要 A => B(和 B => A)共享元素转换,而不再关心从 B => C 再回到 A 的任何转换。

示例

查看我基于android的动画示例创建的example,其中Activity A = MainActivity,B = DetailActivity,C = DetailDetailActivity。单击 Activity B 上的按钮将导航到 Activity C。

【问题讨论】:

  • 您好,您可以分享一下您已经做过的事情,以便我们找出问题所在吗?
  • 嗨@Walid,请查看我的示例 repo,它来自 android 动画示例。
  • 确认一下,开发者选项“不保留活动”是否关闭?
  • @Cliabhach 是的,如果那样的话,你甚至不能做 A -> B -> A。
  • 同样的问题,有解决办法吗?

标签: android android-transitions shared-element-transition


【解决方案1】:

因为在执行 C => B 时,它会为 B 重新构造一个新的 EnterTransitionCoordinator,替换旧的包含正确的mPendingExitNames,这表明视图需要在 A 和 B 之间转换很重要。

public boolean startExitBackTransition(final Activity activity) {
    ArrayList<String> pendingExitNames = getPendingExitNames(); // here
    if (pendingExitNames == null || mCalledExitCoordinator != null) {
        return false;
    } else {
          // ...
     }
}

解决方案似乎有点棘手。可以参考ThreeActivityTransitionDemo,关注SharedElementUtils

【讨论】:

  • 我收到了异常java.lang.NoSuchFieldException: No field mPendingExitNames in class Landroid/app/ActivityTransitionState
  • 你已经绕过Android隐藏API限制了吗? Restrictions on non-SDK interfaces 至于我上面提供的演示,我已经导入了一个依赖项me.weishu:free_reflection:3.0.1 并在ThreeActivityApplication#attachBaseContext 调用Reflection.unseal(base),以便在SharedElementUtils 中获取'ActivityTransitionState' 字段。
  • 你是对的。我没有注意到这一点。绕过限制后它正在工作。
  • 不经过反思就可以解决问题吗?
  • 不走运,我更新了 repo 的 README 以进行简短讨论。使用 Fragment 代替 Activity 可以轻松做到。
【解决方案2】:

将此添加到Activity B

@Override
protected void onStop() {
    if(Build.VERSION.SDK_INT == Build.VERSION_CODES.Q && !isFinishing()){
        new Instrumentation().callActivityOnSaveInstanceState(this, new Bundle());
    }
    super.onStop();
}

【讨论】:

  • 我无法尝试您的解决方案,因为我尚未将我的应用程序更新为以 sdk 30 为目标,并且我正在尝试找到一个不仅适用于 android 11 的通用解决方案
  • 好的。 new Instrumentation().callActivityOnSaveInstanceState(this, new Bundle()); 没有版本调用在较低的 sdk 上工作吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-07
  • 1970-01-01
  • 2015-10-26
  • 2018-07-30
  • 1970-01-01
相关资源
最近更新 更多