1

I have a custom view containing two rows with 4 other custom views each and borders around every one of those 8 custom views.

enter image description here

In the xml I'm using ConstraintLayout and I have two invisible views for the first row and the second row which help me with making the views having the same width-s and height-s.

Design is working great but what annoys me is that the rendering is too slow. I tried removing the constraints of the views and it appears to be working way faster without them.

My questions is: is there a way to improve the performance of this view or is that the right way of doing this.

Here's the xml I'm using:

<?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>
WWJD
  • 1,104
  • 4
  • 12
  • 31
  • 1
    Have you tried with a simple GridView instead of ConstraintLayout? – Todor Kostov Jan 09 '18 at 08:33
  • 2
    Have you gone through: https://developer.android.com/training/improving-layouts/index.html and reviewed your layout in the `Hierarchy Viewer` – Morrison Chang Jan 09 '18 at 08:34
  • @TodorKostov I forgot to mention this but I need to have control over the borders of each item. As shown in the image I provided I want to be able to change the color of the borders when item is enabled/disabled. Would I be able to replicate this behavior with `GridView`? – WWJD Jan 09 '18 at 08:41
  • 1
    I believe it will be possible. You still have your custom views, but instead of 2 ConstraintLayouts, you will have just a single GridView. That will reduce the complexity of the overall layout IMO. – Todor Kostov Jan 09 '18 at 08:49

2 Answers2

3

There different ways to optimize the layout. First of all nested ConstraintLayout is a bad idea.

1) You should remove all border Views and create shape and set as background to your FilterObjectTypeWithImageView view. Removing 26 Views is a big win, and your layout will be more readable.

Here is how

2) Instead of using nested constraint layout, you can use 3 vertical Guidlines. With percent values 25% , 50%, 75% and constraint all views to the constraint. Your custom views will be 1/4 of screen and app:layout_constraintDimensionRatio="1:1" will make the same height.

enter image description here

At the end you will have 3 Guidlines and 4 Custom views, it will be much faster and simpler layout.

Misha Akopov
  • 12,241
  • 27
  • 68
  • 82
-1

I fixed the performance issues by applying 3 vertical guidelines and by removing the app:layout_constraintDimensionRatio="1:1" for the 8 items in the grid as it is unnecessary by this point.

WWJD
  • 1,104
  • 4
  • 12
  • 31