【问题标题】:Android custom view renders slowlyAndroid 自定义视图渲染缓慢
【发布时间】:2013-09-27 15:58:13
【问题描述】:

//应用程序应该如何运行 我正在编写一个 android 应用程序,我正在尝试显示 6 个“信息卡”,这些“信息卡”排列在 2 卡 X 3 卡网格(行 x 列)中,位于我的家庭活动的查看器内。当活动开始时,用户将看到 6 张卡片以网格形式排列。他们将能够使用滑动动作,这将导致原来的 6 张卡片滑出屏幕,另外 6 张卡片将滑到屏幕上。

//卡片详情 卡片本身有点像表格,因为每张卡片都有相同的信息字段,但每张卡片在每个字段中都有不同的信息(例如,每张卡片都有一个显示卡片名称的 textView,但每个卡片在文本视图中显示了不同的名称)。为了实现这一点,我创建了一个卡片类,它扩展卡片的 XML 布局,然后使用每个卡片自定义的信息填充每个 textView、imageView 等。然后将此视图添加为片段的视图,因此屏幕上显示的每张卡片实际上都是一个片段,并显示在我的 2 X 3 网格中,该网格也是一个片段,位于查看器内部。所以,我有一个卡片片段,它被放置在另一个网格片段中,用作 ViewPager 的页面。此外,这些卡片是可翻转的,因此它们有正面和背面。我正在使用单个布局文件为卡片创建正面和背面。当我想显示卡片的正面或背面时,我会选择性地显示/隐藏正面布局或背面布局。

//问题 我的问题是,当我等待卡片渲染时,应用程序启动时会有 6 - 10 秒的延迟(使用 Galaxy Tab 10.1 和 Nexus 7)。所有的卡数据都是本地的,所以我知道我不是在等待 Web 服务返回数据,我肯定手头有数据并且可以使用。我相信延迟时间可能是由于我必须渲染这些包含许多布局和小部件的卡片。此外,在运行时,我永远不知道需要渲染多少张卡片,所以我总是以编程方式创建卡片片段的实例。

//我调查过的事情 因为我将卡片创建为片段,所以我尝试过的一件事是用具有更简单布局的不同片段替换卡片片段。我发现使用布局更简单的片段可以将渲染速度提高到可以接受的水平。

//我的问题 我现在真的不知道该怎么做才能减少用卡片渲染屏幕所需的时间。我正在尝试使卡片的 XML 布局尽可能简单,但在某些时候我无法再简化它们而不影响它们的设计。我正在寻找有关如何在没有看到我所看到的性能影响的情况下渲染具有大量小部件的布局的建议。渲染复杂布局是否有任何提示或技巧?完全以编程方式定义我的卡片(没有 XML 布局)有帮助吗?您可以看到任何明显的错误吗?

任何帮助将不胜感激。谢谢!

//卡片的XML布局

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <RelativeLayout
        android:layout_width="257dp"
        android:layout_height="343dp"
        android:id="@+id/cardContainerRL"
        android:layout_centerInParent="true">

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:id="@+id/cardFrontRL">

            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="vertical"
                >

                <RelativeLayout
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:id="@+id/frontUpperRL"
                    android:layout_weight="1"
                    android:focusable="false"
                    android:background="@drawable/card_top_note">

                    <RelativeLayout
                        android:layout_width="fill_parent"
                        android:layout_height="50dp"
                        android:id="@+id/frontHeader">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Waiting to be completed"
                            android:id="@+id/frontStatusTV"
                            android:layout_alignParentTop="false"
                            android:singleLine="false"
                            android:layout_centerInParent="true"
                            android:textSize="12dp"/>

                        <ImageView
                            android:layout_width="20dp"
                            android:layout_height="20dp"
                            android:id="@+id/frontStarIV"
                            android:src="@drawable/cool_star"
                            android:adjustViewBounds="true"
                            android:layout_toLeftOf="@+id/frontStatusTV"
                            android:layout_centerVertical="true"
                            android:longClickable="true"/>

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="1"
                            android:id="@+id/numMessagesTV"
                            android:layout_alignParentTop="true"
                            android:layout_alignParentRight="true"
                            android:layout_marginRight="2dp"/>
                    </RelativeLayout>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Walk the Dogs Yo!"
                        android:id="@+id/frontTaskTV"
                        android:layout_below="@+id/frontHeader"
                        android:layout_marginTop="5dp"
                        android:layout_centerHorizontal="true"
                        android:textSize="22dp"/>

                </RelativeLayout>

                <RelativeLayout
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:id="@+id/frontLowerRL"
                    android:layout_weight="1"
                    android:focusableInTouchMode="true"
                    >

                    <RelativeLayout
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"
                        android:id="@+id/imageClip"
                        android:background="@drawable/card_bottom">
                    </RelativeLayout>

                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:id="@+id/cardImageIV"
                        android:layout_marginLeft="4dp"
                        android:layout_marginRight="4dp"
                        android:layout_marginBottom="4dp"
                        android:src="@drawable/bulldog"
                        android:adjustViewBounds="true"
                        android:scaleType="fitXY"/>
                </RelativeLayout>

            </LinearLayout>

            <TextView
                android:layout_width="77dp"
                android:layout_height="77dp"
                android:text="666"
                android:id="@+id/cardPointsTV"
                android:layout_centerInParent="true"
                android:singleLine="true"
                android:background="@drawable/points_circle"
                android:gravity="center_vertical|center_horizontal"
                android:textSize="24dp"
                android:textStyle="bold"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Due on Sat. Nov 13"
                android:id="@+id/frontDateTV"
                android:layout_above="@+id/cardPointsTV"
                android:layout_centerHorizontal="true"
                android:textSize="15dp"/>
        </RelativeLayout>

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical"
            android:id="@+id/cardBackLL">

            <RelativeLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:id="@+id/backUpper"
                android:layout_weight=".65"
                android:background="@drawable/card_top">

                <RelativeLayout
                    android:layout_width="fill_parent"
                    android:layout_height="@dimen/back_header_height"
                    android:id="@+id/backHeader"
                    android:layout_alignParentTop="true"
                    android:layout_alignParentLeft="true"
                    android:layout_alignParentRight="true">

                    <ImageView
                        android:layout_width="@dimen/back_star_width"
                        android:layout_height="@dimen/back_star_width"
                        android:id="@+id/backStarIV"
                        android:layout_alignParentTop="false"
                        android:layout_alignParentLeft="false"
                        android:src="@drawable/cool_star"
                        android:scaleType="fitXY"
                        android:layout_marginLeft="@dimen/back_star_margin_left"
                        android:layout_centerVertical="true"/>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="To be completed"
                        android:id="@+id/backStatusTV"
                        android:layout_centerVertical="true"
                        android:singleLine="false"
                        android:textSize="@dimen/back_status_font_size"
                        android:layout_marginLeft="@dimen/card_back_detail_text_margin_left"/>

                    <LinearLayout
                        android:orientation="vertical"
                        android:layout_width="wrap_content"
                        android:layout_height="fill_parent"
                        android:layout_alignParentRight="true"
                        android:layout_alignParentTop="false"
                        android:layout_alignParentBottom="false"
                        android:layout_marginRight="@dimen/card_back_points_container_margin_right">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="fill_parent"
                            android:text="POINTS"
                            android:id="@+id/POINTS"
                            android:layout_alignParentRight="true"
                            android:textSize="@dimen/back_card_points_font_size"
                            android:layout_weight="1"
                            android:gravity="bottom"/>

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="fill_parent"
                            android:text="666"
                            android:id="@+id/backPointsTV"
                            android:layout_alignParentRight="true"
                            android:textColor="@color/dark_gray"
                            android:layout_alignParentBottom="true"
                            android:textStyle="bold"
                            android:textSize="@dimen/back_card_point_value_font_size"
                            android:layout_weight="1"
                            android:gravity="top"/>
                    </LinearLayout>

                </RelativeLayout>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Walk the Dogs Yo!"
                    android:id="@+id/backTaskTV"
                    android:layout_below="@+id/backHeader"
                    android:phoneNumber="true"
                    android:textSize="@dimen/card_back_taskname_font_size"
                    android:textIsSelectable="false"
                    android:layout_marginLeft="@dimen/card_back_detail_text_margin_left"
                    android:maxLines="2"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="DUE ON"
                    android:id="@+id/dueOnTV"
                    android:layout_alignLeft="@+id/backHeader"
                    android:layout_alignParentBottom="true"
                    android:textSize="12dp"
                    android:textIsSelectable="false"
                    android:layout_marginLeft="@dimen/card_back_detail_text_margin_left"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Sun. May 14"
                    android:id="@+id/backDateTV"
                    android:textSize="12dp"
                    android:textStyle="italic"
                    android:layout_toRightOf="@+id/dueOnTV"
                    android:layout_alignTop="@+id/dueOnTV"
                    android:layout_marginLeft="4dp"
            </RelativeLayout>

            <RelativeLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:id="@+id/backLower"
                android:layout_weight=".35"
                android:background="@drawable/card_bottom">

                <RelativeLayout
                    android:layout_width="fill_parent"
                    android:layout_height="49dp"
                    android:layout_alignParentBottom="true"
                    android:layout_alignParentLeft="true"
                    android:layout_alignParentRight="true"

                    <ImageView
                        android:layout_width="@dimen/back_button_width"
                        android:layout_height="@dimen/back_button_height"
                        android:id="@+id/backArrowIV"
                        android:layout_alignParentLeft="true"
                        android:src="@drawable/btn_back"
                        android:layout_centerVertical="true"
                        android:layout_marginRight="@dimen/arrow_button_margin_right"
                        android:scaleType="fitXY"/>

                    <view
                        android:layout_width="@dimen/back_buttons_width"
                        android:layout_height="@dimen/back_buttons_height"
                        class="com.android.ui.widgets.ActionButton"
                        android:id="@+id/editButton"
                        android:layout_centerVertical="true"
                        android:layout_alignParentRight="true"
                        android:layout_marginRight="@dimen/send_button_margin_right"/>

                    <view
                        android:layout_width="@dimen/back_buttons_width"
                        android:layout_height="@dimen/back_buttons_height"
                        class="com.android.ui.widgets.ActionButton"
                        android:id="@+id/sendMessageButton"
                        android:layout_centerVertical="true"
                        android:layout_toLeftOf="@+id/editButton"
                        android:layout_marginRight="@dimen/edit_button_margin_right"/>

                </RelativeLayout>
            </RelativeLayout>
        </LinearLayout>

    </RelativeLayout>

</RelativeLayout>

【问题讨论】:

    标签: performance rendering


    【解决方案1】:

    没有冒犯,您确实需要检查您的布局。 使用比这个轻 5-10 倍的布局可以创建更复杂的视图。 你有:

    <RelativeLayout> <!-- DISPATCH MEASURE LAYOUT DRAW -->
        <RelativeLayout> <!-- DISPATCH MEASURE LAYOUT DRAW -->
           <RelativeLayout> <!-- DISPATCH MEASURE LAYOUT DRAW -->
                <LinearLayout> <!-- DISPATCH MEASURE LAYOUT DRAW -->
                    <RelativeLayout> <!-- DISPATCH MEASURE LAYOUT DRAW -->
                        <RelativeLayout"> <!--DISPATCH MEASURE LAYOUT DRAW -->
                            <TextView/> <!-- MEASURE LAYOUT DRAW -->
                            <ImageView/> <!-- MEASURE LAYOUT DRAW -->
                            <TextView/> <!-- MEASURE LAYOUT DRAW -->
                        </RelativeLayout> 
                        <TextView/> <!-- MEASURE LAYOUT DRAW -->
                    </RelativeLayout>
                    <RelativeLayout> <!-- DISPATCH MEASURE LAYOUT DRAW -->
                        <RelativeLayout> <!--DISPATCH MEASURE LAYOUT DRAW -->
                        </RelativeLayout>
                        <ImageView/> <!-- MEASURE LAYOUT DRAW -->
                    </RelativeLayout>
                </LinearLayout>
                <TextView/> <!-- MEASURE LAYOUT DRAW -->
                <TextView/> <!-- MEASURE LAYOUT DRAW -->
            </RelativeLayout>
            <LinearLayout> <!-- DISPATCH MEASURE LAYOUT DRAW -->
               <RelativeLayout> <!-- DISPATCH MEASURE LAYOUT DRAW -->
                    <RelativeLayout> <!-- DISPATCH MEASURE LAYOUT DRAW-->
                        <ImageView/> <!-- MEASURE LAYOUT DRAW -->
                        <TextView/> <!-- MEASURE LAYOUT DRAW -->
                        <LinearLayout> <!-- DISPATCH MEASURE LAYOUT DRAW -->
                            <TextView/> <!-- MEASURE LAYOUT DRAW -->
                            <TextView/> <!-- MEASURE LAYOUT DRAW -->
                        </LinearLayout>
                    </RelativeLayout>
                    <TextView /> <!-- MEASURE LAYOUT DRAW -->
                    <TextView /> <!-- MEASURE LAYOUT DRAW -->
                    <TextView /> <!-- MEASURE LAYOUT DRAW -->
                </RelativeLayout>
                <RelativeLayout> <!-- DISPATCH MEASURE LAYOUT DRAW -->
                   <RelativeLayout> <!-- DISPATCH MEASURE LAYOUT DRAW -->
                        <ImageView /> <!-- MEASURE LAYOUT DRAW -->
                        <view /> <!-- MEASURE LAYOUT DRAW -->
                        <view /> <!-- MEASURE LAYOUT DRAW -->
                   </RelativeLayout>
                </RelativeLayout>
            </LinearLayout>
        </RelativeLayout>
    </RelativeLayout>
    

    即使在小型设备上解析此布局也需要一些时间。而且这只是为了创建,我不想考虑用这样的视图层次来调度触摸事件。

    如果您真的无法提供更轻的布局。 你可以:

    干杯, 山姆。

    来源:Google 和多年的 Android 开发经验。

    【讨论】:

    • 我最终废弃了所有嵌套布局,并设法将所有内容放入两个单独的相对布局中。一张用于卡片的正面,一张用于卡片的背面。在每个相对布局中,我能够使用我在 dimen 文件中设置的 dps 放置每个 UI 元素。这确实使视图层次结构变平并大大提高了性能。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-07-06
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多