由 30 多个视图组成的自定义视图呈现缓慢

Slow rendering of a custom view made of over 30 views

我有一个自定义视图,其中包含两行,每行有 4 个其他自定义视图,并且围绕着这 8 个自定义视图中的每一个。

在 xml 中,我使用 ConstraintLayout 并且第一行和第二行有两个不可见的视图,这有助于我使视图具有相同的 width -s 和 height-s.

设计效果很好,但令我烦恼的是渲染速度太慢。我尝试删除视图的 constraints,没有它们似乎工作得更快。

我的问题是:有没有办法提高这个视图的性能,或者这是正确的方法。

这是我正在使用的xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.constraint.ConstraintLayout
        android:id="@+id/first_row"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="4:1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.my.app.presentation.component.FilterObjectTypeWithImageView
        android:id="@+id/all_background_filter_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        custom:text="@string/filter_all"
        android:visibility="invisible"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintEnd_toStartOf="@id/stay_filter_view"
        app:layout_constraintStart_toStartOf="@id/first_row"
        app:layout_constraintTop_toTopOf="@id/first_row"
        app:layout_constraintBottom_toBottomOf="@id/first_row"/>

    <com.my.app.presentation.component.FilterObjectTypeIconlessView
        android:id="@+id/all_filter_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        custom:text="@string/filter_all"
        app:layout_constraintStart_toStartOf="@id/all_background_filter_view"
        app:layout_constraintEnd_toEndOf="@id/all_background_filter_view"
        app:layout_constraintTop_toTopOf="@id/all_background_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/all_background_filter_view"/>

    <com.my.app.presentation.component.FilterObjectTypeWithImageView
        android:id="@+id/stay_filter_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintEnd_toStartOf="@id/restaurants_filter_view"
        app:layout_constraintStart_toEndOf="@id/all_background_filter_view"
        app:layout_constraintTop_toTopOf="@id/first_row"
        app:layout_constraintBottom_toBottomOf="@id/first_row"
        custom:src="@drawable/icon__accomodation__x3"
        custom:text="@string/filter_stay" />

    <com.my.app.presentation.component.FilterObjectTypeWithImageView
        android:id="@+id/restaurants_filter_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        custom:text="@string/filter_restaurants"
        custom:src="@drawable/icon__restaurant__x3"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintStart_toEndOf="@id/stay_filter_view"
        app:layout_constraintEnd_toStartOf="@id/shops_filter_view"
        app:layout_constraintTop_toTopOf="@id/first_row"
        app:layout_constraintBottom_toBottomOf="@id/first_row"  />

    <com.my.app.presentation.component.FilterObjectTypeWithImageView
        android:id="@+id/shops_filter_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        custom:text="@string/filter_shops"
        custom:src="@drawable/icon__shop__x3"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintStart_toEndOf="@id/restaurants_filter_view"
        app:layout_constraintTop_toTopOf="@id/first_row"
        app:layout_constraintBottom_toBottomOf="@id/first_row"
        app:layout_constraintEnd_toEndOf="@id/first_row"/>

   <android.support.constraint.ConstraintLayout
        android:id="@+id/second_row"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="4:1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/first_row" />

    <com.my.app.presentation.component.FilterObjectTypeWithImageView
        android:id="@+id/sights_filter_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        custom:text="@string/filter_sights"
        custom:src="@drawable/icon__sights__x3"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintStart_toStartOf="@id/second_row"
        app:layout_constraintEnd_toStartOf="@id/sports_filter_view"
        app:layout_constraintTop_toTopOf="@id/second_row"
        app:layout_constraintBottom_toBottomOf="@id/second_row"
        />

    <com.my.app.presentation.component.FilterObjectTypeWithImageView
        android:id="@+id/sports_filter_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        custom:text="@string/filter_sports"
        custom:src="@drawable/icon__sport__x3"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintStart_toEndOf="@id/sights_filter_view"
        app:layout_constraintEnd_toStartOf="@id/educational_filter_view"
        app:layout_constraintTop_toTopOf="@id/second_row"
        app:layout_constraintBottom_toBottomOf="@id/second_row"/>

    <com.my.app.presentation.component.FilterObjectTypeWithImageView
        android:id="@+id/educational_filter_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        custom:text="@string/filter_educational"
        custom:src="@drawable/icon__study__x3"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintStart_toEndOf="@id/sports_filter_view"
        app:layout_constraintEnd_toStartOf="@id/public_filter_view"
        app:layout_constraintTop_toTopOf="@id/second_row"
        app:layout_constraintBottom_toBottomOf="@id/second_row"/>

    <com.my.app.presentation.component.FilterObjectTypeWithImageView
        android:id="@+id/public_filter_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        custom:text="@string/filter_public"
        custom:src="@drawable/icon__public__x3"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintEnd_toEndOf="@id/second_row"
        app:layout_constraintTop_toTopOf="@id/second_row"
        app:layout_constraintStart_toEndOf="@id/educational_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/second_row"/>

    <View
        android:id="@+id/all_filter_top_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/all_filter_view"
        app:layout_constraintEnd_toStartOf="@id/stay_filter_view"
        app:layout_constraintTop_toTopOf="parent"/>

    <View
        android:id="@+id/all_filter_bottom_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/all_filter_view"
        app:layout_constraintEnd_toStartOf="@id/stay_filter_view"
        app:layout_constraintTop_toBottomOf="@id/all_filter_view"/>

    <View
        android:id="@+id/stay_filter_top_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/stay_filter_view"
        app:layout_constraintEnd_toStartOf="@id/restaurants_filter_view"
        app:layout_constraintTop_toTopOf="@id/stay_filter_view"/>

    <View
        android:id="@+id/stay_filter_bottom_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/stay_filter_view"
        app:layout_constraintEnd_toStartOf="@id/restaurants_filter_view"
        app:layout_constraintTop_toBottomOf="@id/stay_filter_view"/>

    <View
        android:id="@+id/restaurants_filter_top_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/restaurants_filter_view"
        app:layout_constraintEnd_toStartOf="@id/shops_filter_view"
        app:layout_constraintTop_toTopOf="parent"/>

    <View
        android:id="@+id/restaurants_filter_bottom_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/restaurants_filter_view"
        app:layout_constraintEnd_toStartOf="@id/shops_filter_view"
        app:layout_constraintTop_toBottomOf="@id/restaurants_filter_view"/>

    <View
        android:id="@+id/shops_filter_top_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/shops_filter_view"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <View
        android:id="@+id/shops_filter_bottom_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/shops_filter_view"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/shops_filter_view"/>

    <View
        android:id="@+id/sights_filter_bottom_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/sights_filter_view"
        app:layout_constraintEnd_toStartOf="@id/sports_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/sights_filter_view"/>

    <View
        android:id="@+id/sports_filter_bottom_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/sports_filter_view"
        app:layout_constraintEnd_toStartOf="@id/educational_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/sports_filter_view"/>

    <View
        android:id="@+id/educational_filter_bottom_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/educational_filter_view"
        app:layout_constraintEnd_toStartOf="@id/public_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/educational_filter_view"/>

    <View
        android:id="@+id/public_filter_bottom_border"
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toStartOf="@id/public_filter_view"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="@id/public_filter_view"/>

    <View
        android:id="@+id/all_filter_left_border"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintTop_toTopOf="@id/all_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/all_filter_view"
        app:layout_constraintStart_toStartOf="@id/all_filter_view"/>

    <View
        android:id="@+id/sights_filter_left_border"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintTop_toTopOf="@id/sights_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/sights_filter_view"
        app:layout_constraintStart_toStartOf="@id/sights_filter_view"/>


    <View
        android:id="@+id/stay_filter_left_border"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintTop_toTopOf="@id/stay_filter_view"
        app:layout_constraintBottom_toTopOf="@id/sports_filter_view"
        app:layout_constraintStart_toStartOf="@id/stay_filter_view"/>

    <View
        android:id="@+id/sports_filter_left_border"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintTop_toTopOf="@id/sports_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/sports_filter_view"
        app:layout_constraintStart_toStartOf="@id/sports_filter_view"/>

    <View
        android:id="@+id/restaurants_filter_left_border"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintTop_toTopOf="@id/restaurants_filter_view"
        app:layout_constraintBottom_toTopOf="@id/educational_filter_view"
        app:layout_constraintStart_toStartOf="@id/restaurants_filter_view"/>

    <View
        android:id="@+id/educational_filter_left_border"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintTop_toTopOf="@id/educational_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/educational_filter_view"
        app:layout_constraintStart_toStartOf="@id/educational_filter_view"/>

    <View
        android:id="@+id/shops_filter_left_border"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintTop_toTopOf="@id/shops_filter_view"
        app:layout_constraintBottom_toTopOf="@id/public_filter_view"
        app:layout_constraintStart_toStartOf="@id/shops_filter_view"/>

    <View
        android:id="@+id/public_filter_left_border"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintTop_toTopOf="@id/public_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/public_filter_view"
        app:layout_constraintStart_toStartOf="@id/public_filter_view"/>


    <View
        android:id="@+id/shops_filter_right_border"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintTop_toTopOf="@id/shops_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/shops_filter_view"
        app:layout_constraintEnd_toEndOf="@id/shops_filter_view"/>

    <View
        android:id="@+id/public_filter_right_border"
        android:layout_width="1dp"
        android:layout_height="0dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintTop_toTopOf="@id/public_filter_view"
        app:layout_constraintBottom_toBottomOf="@id/public_filter_view"
        app:layout_constraintEnd_toEndOf="@id/public_filter_view"/>

    <View
        android:id="@+id/first_border_center_pixel"
        android:layout_width="1dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toEndOf="@id/all_filter_bottom_border"
        app:layout_constraintBottom_toBottomOf="@id/all_filter_bottom_border" />

    <View
        android:id="@+id/second_border_center_pixel"
        android:layout_width="1dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toEndOf="@id/stay_filter_bottom_border"
        app:layout_constraintBottom_toBottomOf="@id/stay_filter_bottom_border" />

    <View
        android:id="@+id/third_border_center_pixel"
        android:layout_width="1dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintStart_toEndOf="@id/restaurants_filter_bottom_border"
        app:layout_constraintBottom_toBottomOf="@id/restaurants_filter_bottom_border" />

    <View
        android:id="@+id/fourth_border_center_pixel"
        android:layout_width="1dp"
        android:layout_height="1dp"
        android:background="@color/filterUnactivatedColor"
        app:layout_constraintEnd_toEndOf="@id/shops_filter_bottom_border"
        app:layout_constraintBottom_toBottomOf="@id/shops_filter_bottom_border" />

</android.support.constraint.ConstraintLayout>

有多种优化布局的方法。首先嵌套 ConstraintLayout 是个坏主意。

1) 您应该删除所有边框视图并创建形状并设置为您的 FilterObjectTypeWithImageView 视图的背景。删除 26 个视图是一个巨大的胜利,您的布局将更具可读性。

Here is how

2)不用嵌套约束布局,可以用3纵Guidlines。使用百分比值 25% 、 50% 、 75% 并约束所有视图到约束。您的自定义视图将占屏幕的 1/4,app:layout_constraintDimensionRatio="1:1" 将达到相同的高度。

最后你会有 3 个 Guidlines 和 4 个自定义视图,它会更快更简单 layout

我通过应用 3 vertical guidelines 和删除 grid 中 8 项的 app:layout_constraintDimensionRatio="1:1" 解决了性能问题,因为此时它是不必要的。