场景转换中使用英雄元素会导致图层超出GPU支持的最大尺寸限制。

25

我正在尝试在Android 5.0中对ListView中的图像进行英雄式转换以显示详细页面。但是,大约50%的图像会导致Android崩溃并出现以下异常。我的图像尺寸为600x400,但我尝试将它们更改为200x100,但出现了相同的错误。当它正常工作时,看起来非常棒,但我无法看出不同图像之间的区别。我真的不知道为什么它声称图层太大,有人有线索吗?

private void handleNewsItemClicked(AdapterView<?> arg0, View viewClicked, int arg2) {
    TopNewsItem item = ((TopNewsItem)arg0.getAdapter().getItem(arg2));
        Intent intent = new Intent(getActivity(), TopNewsDetailsActivity.class);
        intent.putExtra(TopNewsDetailsActivity.ARGS_ID, item.getGuid().getId());
        intent.putExtra(TopNewsDetailsActivity.ARGS_IMAGE,  imageUrl);
        if(Build.VERSION.SDK_INT >= 21) {                                 
            ActivityOptions options = ActivityOptions
                    .makeSceneTransitionAnimation(this.getActivity(),
                            viewClicked.findViewById(R.id.image), "article_image");                
            this.getActivity().startActivity(intent, options.toBundle());
        }else
            getActivity().startActivity(intent);
    }
}

W/OpenGLRenderer(18137): Layer exceeds max. dimensions supported by the GPU (1080x4628, max=4096x4096)
D/AndroidRuntime(18137): Shutting down VM
V/GAV3    (18137): Thread[main,5,main]: Tracking Exception: IllegalStateException (@MessageQueue:nativePollOnce:-2) {main}
/AndroidRuntime(18137): FATAL EXCEPTION: main
E/AndroidRuntime(18137): Process: myapp.app, PID: 18137
E/AndroidRuntime(18137): java.lang.IllegalStateException: Unable to create layer for  RelativeLayout
E/AndroidRuntime(18137):    at android.os.MessageQueue.nativePollOnce(Native Method)
E/AndroidRuntime(18137):    at android.os.MessageQueue.next(MessageQueue.java:143)
E/AndroidRuntime(18137):    at android.os.Looper.loop(Looper.java:122)
E/AndroidRuntime(18137):    at android.app.ActivityThread.main(ActivityThread.java:5221)
E/AndroidRuntime(18137):    at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(18137):    at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime(18137):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
E/AndroidRuntime(18137):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

FYI,我在 Android 上报告了这个漏洞:https://code.google.com/p/android/issues/detail?id=167551&thanks=167551&ts=1429258132 - gphilip
3个回答

50

当您的视图具有“hasOverlappingRendering()”返回true时,淡入淡出转换将使用硬件层。这是为了提高性能。您必须有许多视图单独淡出。

您有几个选项。其中一个是使您的视图具有hasOverlappingRendering返回false。这在某些情况下可能不可行,但足以解决您的问题。请记住,这意味着包含的视图不应重叠!

第二种方法是分别转换较少的视图。您可以通过在应该一起淡出的ViewGroups上设置android:transitionGroup =“true”来实现此目的。例如,如果您有一个没有背景的ListView,则最终会单独转换每个元素。相反,您可以将ListView的transitionGroup属性设置为true,然后它们将一起转换。

- 更新 -

您遇到的问题是淡入的传入视图太大了。我在启动Activity中尝试了以下视图:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:onClick="clicked"
    >
    <TextView
        android:id="@+id/hello_world"
        android:transitionName="hello"
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

是的,这是一个与Android相关的基本应用程序,给文本赋予id和transitionName。onClick处理程序仅启动第二个Activity,将hello world View作为共享元素传递。第二个Activity有一个非常大的TextView,类似于您的:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:transitionGroup="true"
    >
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/hello_world"
            android:transitionName="hello"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="@string/hello_world" />
        <TextView
            android:layout_below="@+id/hello_world"
            android:text="Lorem ipsum.... I didn't copy all of my text"
            android:textSize="30sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    </RelativeLayout>
</ScrollView>

将ScrollView的transitionGroup从false(默认值)改为true可以使其正常工作,因为此时ScrollView会被淡入。ScrollView有一个最大尺寸,而其内容可以非常庞大。


2
问题在于文章太长,而不是图片太大,对吗?我想你在详细活动中有类似这样的东西:<ScrollView><Image><TextView></ScrollView>。如果是这样,你想要在详细活动中的 ScrollView 上设置 transitionGroup="true"。我可以写一个示例应用程序来演示。 - George Mount
谢谢你的帮助;我也遇到了同样的问题,它解决了我的问题。结论:当你在一个Activity Transition期间包含可能很大的元素(如TextView)的ScrollView时,你应该始终将其transitionGroup属性设置为true。 - BladeCoder
@GeorgeMount 这个问题在Android M中又出现了 :-/ http://stackoverflow.com/questions/32071265/android-m-scene-transition-with-hero-elements-throws-java-lang-illegalstateexce - Christer Nordvik
@GeorgeMount 如果我的共享元素包含在一个transitionGroup=true的viewgroup中,这会阻止共享元素与其兄弟视图分别进行动画吗? - android_student
不应该。当transitionGroup=true时,共享元素应该单独动画运行而不是与其父级同时动画。某些过渡在切换时会创建位图副本,其中可能包括共享元素的位图,并且您将获得有趣的效果。在Activity Transitions的情况下,我认为任何内置的过渡都不会出现这个问题。 - George Mount
显示剩余13条评论

8
这个问题的根本原因在你的日志中的这一行被指出:W/OpenGLRenderer(18137): Layer exceeds max. dimensions supported by the GPU (1080x4628, max=4096x4096)。目标活动的高度为4628,超过了GPU支持的最大值4096。
解决方案已经在其他答案中提到,即创建一个更短的目标活动。类似的问题和答案可以在这里找到:crash - material design android 5.0。请注意保留HTML标记。

非常感谢您的解释。我遇到了“无法为RelativeLayout创建图层,大小为768x7040,最大大小为8192,颜色类型为4,具有上下文1”的错误,这让我感到困惑,因为报告的高度(7040)小于最大大小(8192)。那么为什么会出现这个错误呢? - Soheil

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接