【问题标题】:Shared Element transition crash on Samsung device running Android 8.0运行 Android 8.0 的三星设备上的共享元素转换崩溃
【发布时间】:2018-11-23 17:06:41
【问题描述】:

我遇到了一个奇怪的崩溃,显然无法修复在仅运行 Android 8.0 的三星设备上发生。

我在 Fragment 中填充了一个 recyclerView,它正在启动一个 Activity。

这是我的 ItemHolder 布局

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="@dimen/table_card_header_size"
android:transitionName="@string/team_profile_transition"
android:id="@+id/tableRowMainContainer"
android:background="@drawable/rounded_rect_top"
> ...

这是我对共享元素的活动的意图

private val teamProfileOnClick = View.OnClickListener { v ->
    val teamContainer = v.findViewById<FrameLayout>(R.id.tableRowMainContainer)
    val tag = v.tag as TableRow
    val intent = Intent(context, TeamProfileActivity::class.java)
    intent.putExtra(TeamProfileActivity.TEAM_ID_PROFILE, tag.teamId)
    intent.putExtra(TeamProfileActivity.TEAM_NAME, tag.team.name)
    intent.putExtra(TeamProfileActivity.TEAM_COMPETITION_ID, tableCompetitionId)
    intent.putExtra(TeamProfileActivity.TEAM_TYPE, tag.team.teamType)

    val options = ActivityOptionsCompat.makeSceneTransitionAnimation(context as Activity,
            teamContainer,
            ViewCompat.getTransitionName(teamContainer))
    context.startActivity(intent, options.toBundle())
}

这是目标活动的布局

<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tool="http://schemas.android.com/tools"
android:id="@+id/cardview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:transitionName="@string/team_profile_transition"
app:cardCornerRadius="10dp"
> ...

这是崩溃日志

java.lang.NullPointerException: 
  at android.app.ActivityTransitionCoordinator.setSharedElementState (ActivityTransitionCoordinator.java:553)
  at android.app.ActivityTransitionCoordinator.setSharedElementState (ActivityTransitionCoordinator.java:653)
  at android.app.EnterTransitionCoordinator.startSharedElementTransition (EnterTransitionCoordinator.java:428)
  at android.app.EnterTransitionCoordinator.-wrap4 (Unknown Source)
  at android.app.EnterTransitionCoordinator$3.lambda$-android_app_EnterTransitionCoordinator$3_18867 (EnterTransitionCoordinator.java:492)
  at android.app.-$Lambda$CsyQO--8YdRe5wlajUCi-L98enA$1.$m$0 (Unknown Source:8)
  at android.app.-$Lambda$CsyQO--8YdRe5wlajUCi-L98enA$1.run (Unknown Source)
  at android.app.ActivityTransitionCoordinator.startTransition (ActivityTransitionCoordinator.java:902)
  at android.app.EnterTransitionCoordinator$3.lambda$-android_app_EnterTransitionCoordinator$3_18819 (EnterTransitionCoordinator.java:491)
  at android.app.-$Lambda$CsyQO--8YdRe5wlajUCi-L98enA$2.$m$0 (Unknown Source:8)
  at android.app.-$Lambda$CsyQO--8YdRe5wlajUCi-L98enA$2.run (Unknown Source)
  at com.android.internal.view.OneShotPreDrawListener.onPreDraw (OneShotPreDrawListener.java:78)
  at android.view.ViewTreeObserver.dispatchOnPreDraw (ViewTreeObserver.java:1045)
  at android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:2800)
  at android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1779)
  at android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:7810)
  at android.view.Choreographer$CallbackRecord.run (Choreographer.java:911)
  at android.view.Choreographer.doCallbacks (Choreographer.java:723)
  at android.view.Choreographer.doFrame (Choreographer.java:658)
  at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:897)
  at android.os.Handler.handleCallback (Handler.java:789)
  at android.os.Handler.dispatchMessage (Handler.java:98)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6938)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:327)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)

【问题讨论】:

  • 您解决了这个问题吗?我也一样
  • 你是怎么解决这个问题的?
  • 是的,我做到了。请检查我的解决方案

标签: android kotlin samsung-mobile android-transitions shared-element-transition


【解决方案1】:

我找到的解决方案如下: 打开共享元素时冻结/解冻recyclerView:

 override fun onPause() {
    super.onPause()
    tableCardStack.isLayoutFrozen = true
}

override fun onResume() {
    super.onResume()
    tableCardStack.isLayoutFrozen = false
}

我注意到我正在制作动画的视图没有动画回到正确的位置。所以我想冻结布局。我知道这不是最好的解决方案,但我找不到更好的解决方案

【讨论】:

    【解决方案2】:

    看起来某些三星设备不检查视图父级是否为null,这在某些极端情况下可能会发生。您可以通过从过渡中删除没有父级的视图来防止发生这种崩溃。这是通过在您的活动中添加SharedElementCallback 并覆盖onSharedElementEnd 和/或onSharedElementStart(取决于您的进入或退出转换是否崩溃)然后查找并删除如下视图来完成的:

    activity.setEnterSharedElementCallback(object : SharedElementCallback() {
    
        override fun onSharedElementStart(sharedElementNames: MutableList<String>?, sharedElements: MutableList<View>?, sharedElementSnapshots: MutableList<View>?) {
            sharedElements?.removeAll(sharedElements.filter { it.parent == null })
            super.onSharedElementStart(sharedElementNames, sharedElements, sharedElementSnapshots)
        }
    
        override fun onSharedElementEnd(sharedElementNames: MutableList<String>?, sharedElements: MutableList<View>?, sharedElementSnapshots: MutableList<View>?) {
            sharedElements?.removeAll(sharedElements.filter { it.parent == null })
            super.onSharedElementEnd(sharedElementNames, sharedElements, sharedElementSnapshots)
        }
    }
    

    请注意,这并不能消除崩溃的根本原因,只是通过在没有父视图的情况下不为视图设置动画来防止它发生。

    【讨论】:

      猜你喜欢
      • 2017-02-23
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      相关资源
      最近更新 更多