android - Lollipop 设备的共享元素转换崩溃

标签 android xml material-design

我正在使用 ActivityOptions.makeSceneTransitionAnimation API 来处理共享转换。

我面临的问题是它在 Marshmellow 设备上运行但在 Lolipop 设备上崩溃。

这是崩溃日志:

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.ViewGroup.getScrollX()' on a null object reference
   at android.app.ActivityTransitionCoordinator.setSharedElementState(ActivityTransitionCoordinator.java:435)
   at android.app.ActivityTransitionCoordinator.setSharedElementState(ActivityTransitionCoordinator.java:473)
   at android.app.EnterTransitionCoordinator.startSharedElementTransition(EnterTransitionCoordinator.java:332)
   at android.app.EnterTransitionCoordinator.access$200(EnterTransitionCoordinator.java:42)
   at android.app.EnterTransitionCoordinator$5$1.run(EnterTransitionCoordinator.java:389)
   at android.app.ActivityTransitionCoordinator.startTransition(ActivityTransitionCoordinator.java:698)
   at android.app.EnterTransitionCoordinator$5.onPreDraw(EnterTransitionCoordinator.java:386)
   at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847)
   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1990)
   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1088)
   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5825)
   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:769)
   at android.view.Choreographer.doCallbacks(Choreographer.java:582)
   at android.view.Choreographer.doFrame(Choreographer.java:552)
   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:755)
   at android.os.Handler.handleCallback(Handler.java:739)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:135)
   at android.app.ActivityThread.main(ActivityThread.java:5237)
   at java.lang.reflect.Method.invoke(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)

这是我的代码

 @Override
public void getComments(String postId, String authorName, String message, String imageURL, String likesCount, RelativeLayout imageView) {


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && imageView != null) {
        ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(getActivity(), imageView, "revealLayout");

        Intent commentIntent = new Intent(getActivity(), CommentsActivity.class);
        commentIntent.putExtra("postId", postId);
        commentIntent.putExtra("authorName", authorName);
        commentIntent.putExtra("message", message);
        commentIntent.putExtra("imageURL", imageURL);
        commentIntent.putExtra("likesCount", likesCount);
        startActivity(commentIntent, options.toBundle());

    } else {
        Intent commentIntent = new Intent(getActivity(), CommentsActivity.class);
        commentIntent.putExtra("postId", postId);
        commentIntent.putExtra("authorName", authorName);
        commentIntent.putExtra("message", message);
        commentIntent.putExtra("imageURL", imageURL);
        commentIntent.putExtra("likesCount", likesCount);
        startActivity(commentIntent);
    }


}

我通过接口(interface)从适配器回调中获取上述数据

我的 XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/root_layout"
  android:layout_width="match_parent"
  android:transitionName="revealLayout"
  android:layout_height="wrap_content"
  android:background="?android:attr/selectableItemBackground"
  android:orientation="vertical">

在接收端与 android:transitionName 相同的相对布局

这是我的 styles.xml

  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">#c65643</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:windowContentTransitions">true</item>
    <item name="android:windowSharedElementReenterTransition">@null</item>
    <item name="android:windowReenterTransition">@null</item>
    <item name="android:windowAllowReturnTransitionOverlap">false</item>
</style>

还有styles.xml(21)

  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">#c65643</item>
            <item name="colorAccent">@color/colorAccent</item>
            <item name="android:windowContentTransitions">true</item>
            <item name="android:windowSharedElementReenterTransition">@null</item>
            <item name="android:windowReenterTransition">@null</item>
            <item name="android:windowAllowReturnTransitionOverlap">false</item>

    </style>

也通过这个链接https://code.google.com/p/android/issues/detail?id=224270&sort=-id&colspec=ID但没有运气

提前致谢

最佳答案

很明显是Android 5.0的Bug,5.1修复了。 尝试将除ScaleType.MATRIX之外的其他ScaleType设置为Transition ImageView

Android 5.0上的ActivityTransitionCoordinator.java源码

537    protected ArrayList<View> createSnapshots(Bundle state, Collection<String> names) {
538      ...
549        for (String name: names) {
550            Bundle sharedElementBundle = state.getBundle(name);
551            if (sharedElementBundle != null) {
552               ...
557                if (snapshot != null) {
558                    setSharedElementState(snapshot, name, state, null, null, decorLoc);
559                }
560                snapshots.add(snapshot);
561            }
562        }
563        return snapshots;
564    }

Android 5.1 上的 ActivityTransitionCoordinator.java 源代码

629    protected ArrayList<View> createSnapshots(Bundle state, Collection<String> names) {
630       ...
641        Matrix tempMatrix = new Matrix();
642        for (String name: names) {
643            Bundle sharedElementBundle = state.getBundle(name);
644            View snapshot = null;
645            if (sharedElementBundle != null) {
646              ...
650                if (snapshot != null) {
651                    setSharedElementState(snapshot, name, state, tempMatrix, null, decorLoc);
652                }
653            }
655            snapshots.add(snapshot);
656        }
657        return snapshots;
658    }

以及ActivityTransitionCoordinator.setSharedElementState中的崩溃线

376    private void setSharedElementState(View view, String name, Bundle transitionArgs,
377            Matrix tempMatrix, RectF tempRect, int[] decorLoc) {
378        Bundle sharedElementBundle = transitionArgs.getBundle(name);
379        if (sharedElementBundle == null) {
380            return;
381        }
382
383        if (view instanceof ImageView) {
384            int scaleTypeInt = sharedElementBundle.getInt(KEY_SCALE_TYPE, -1);
385            if (scaleTypeInt >= 0) {
386                ImageView imageView = (ImageView) view;
387                ImageView.ScaleType scaleType = SCALE_TYPE_VALUES[scaleTypeInt];
388                imageView.setScaleType(scaleType);
389                if (scaleType == ImageView.ScaleType.MATRIX) {
390                    float[] matrixValues = sharedElementBundle.getFloatArray(KEY_IMAGE_MATRIX);
391                    tempMatrix.setValues(matrixValues);
392                    imageView.setImageMatrix(tempMatrix);
393                }
394            }
395        }
396        ...
450    }

关于android - Lollipop 设备的共享元素转换崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40039803/

相关文章:

android - 从嵌套的 PreferenceScreen 返回时更改摘要

java - 膨胀 ListView 二进制 XML 行 0 时出错#

java - 使用 MOXy 和 XPath,是否可以解码属性列表?

android - 如何更改 NavigationView 的项目文本大小?

html - 集中实现 css 图标

java - Android Tabs + Sliding,如何实现ActionBarSherlock?

java - ProGuard - 应用程序在模拟器中运行良好,但在尝试构建 apk 时失败

android - 我们如何制作带有圆形复选框的 GridView 并在 flutter 中选择颜色

php - 获取根节点的XML命名空间

javascript - sidenav 切换时更改按钮主题( Angular Material )