Zoptymalizuj hierarchie układu

Wypróbuj sposób tworzenia wiadomości
Jetpack Compose to zalecany zestaw narzędzi UI na Androida. Dowiedz się, jak korzystać z układów w funkcji Utwórz

Przekonanie, że układ podstawowy to układ, który jest najskuteczniejszy, jest błędne. Każdy widżet i układ, który dodasz do aplikacji, wymaga zainicjowania, układu i rysowania. Na przykład używanie zagnieżdżonych instancji LinearLayout może prowadzić do zbyt głębokiej hierarchii widoków. Poza tym zagnieżdżanie kilku instancji LinearLayout, które korzystają z parametru layout_weight, może być szczególnie kosztowne, ponieważ każde z nich trzeba mierzyć 2 razy. Jest to szczególnie ważne, gdy układ jest wielokrotnie zwiększany, np. podczas używania w RecyclerView.

W tym dokumencie opisujemy, jak używać inspektora układu i Lint do sprawdzania i optymalizowania układu.

Sprawdzanie układu

Narzędzia Android SDK zawierają narzędzie Inspektor układu, które pozwala analizować układ podczas działania aplikacji. Korzystanie z tego narzędzia pomaga wykryć nieefektywność układu.

Za pomocą inspektora układu możesz wybrać procesy uruchomione na połączonym urządzeniu lub emulatorze, a następnie wyświetlić drzewo układu. Światła uliczne na każdym bloku reprezentują parametry „Pomiar”, „Układ” i „Rysuj”, co pomaga w identyfikacji potencjalnych problemów.

Na przykład na ilustracji 1 widać układ używany jako element RecyclerView. Ten układ pokazuje mały obraz bitmapy po lewej stronie i 2 nałożone na siebie elementy tekstu po prawej. Szczególnie ważne jest, aby układy tego typu, które są wielokrotnie zwiększane, były optymalizowane wraz z pomnożeniem korzyści dotyczących wydajności.

Obraz przedstawiający jeden element listy: 1 obraz i 2 teksty wyrównane w pionie
Rysunek 1. Ogólny układ elementu w: RecyclerView.

Inspektor układu wyświetla listę dostępnych urządzeń i ich aktywnych komponentów. Wybierz komponent na karcie Windows i kliknij Inspektor układu, by wyświetlić hierarchię układu wybranego komponentu. Na przykład na ilustracji 2 widać układ elementu listy przedstawiony na rys. 1.

Ilustracja pokazująca Inspektora układu i kompozycję LinearLayout
Rysunek 2. Hierarchia układu dla układu na ilustracji 1 z wykorzystaniem zagnieżdżonych instancji LinearLayout.

Modyfikowanie układu

Ponieważ z powodu zagnieżdżonego elementu LinearLayout wydajność układu spada, wydajność może wzrosnąć przez jego wyrównanie, czyli nadanie układu płytkim i szerokim, a nie wąskiego i głębokiego. ConstraintLayout jako węzeł główny zezwala na takie układy. Po przekonwertowaniu tego projektu na ConstraintLayout układ stanie się dwupoziomową hierarchią:

    <androidx.constraintlayout.widget.ConstraintLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/root"
      android:layout_width="match_parent"
      android:layout_height="52dp"
      android:background="#e4e6e4"
      android:padding="4dp">

      <ImageView
          android:id="@+id/image"
          android:layout_width="48dp"
          android:layout_height="48dp"
          android:background="#5c5c74"
          android:contentDescription="An example box"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent" />

      <TextView
          android:id="@+id/title"
          android:layout_width="0dp"
          android:layout_height="0dp"
          android:layout_marginStart="4dp"
          android:background="#745c74"
          app:layout_constraintBottom_toTopOf="@+id/subtitle"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toEndOf="@id/image"
          app:layout_constraintTop_toTopOf="parent" />

      <TextView
          android:id="@+id/subtitle"
          android:layout_width="0dp"
          android:layout_height="0dp"
          android:background="#7e8d6e"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="@id/title"
          app:layout_constraintTop_toBottomOf="@+id/title" />
  </androidx.constraintlayout.widget.ConstraintLayout>
    

Inspekcja nowego układu wygląda tak:

Ilustracja pokazująca Inspektora układu 3D
Rysunek 3. Tryb 3D narzędzia Układ 3D.

Zalety tego rozwiązania są mnożone, ponieważ ten układ jest używany w przypadku każdego elementu na liście.

Większość różnic wynika z używania w projekcie LinearLayout właściwości layout_weight, co może spowalniać pomiary. To jeden przykład właściwego zastosowania każdego układu. Zastanów się, czy użycie wagi układu jest konieczne.

W przypadku złożonych układów system może tracić nakład pracy, mierząc ten sam element interfejsu więcej niż raz. Ten zjawisko nazywamy podwójnym opodatkowaniem. Więcej informacji o podwójnym opodatkowaniu i sposobach zapobiegania mu znajdziesz w artykule Hierarchie wyników i widoków.

Użyj linta

Dobrze jest uruchamiać narzędzie lint w plikach układu, by wyszukać możliwe optymalizacje hierarchii widoków. Lint zastępuje narzędzie layoutopt i ma większą funkcjonalność. Oto przykłady reguł lintowania:

  • Używaj elementów rysowanych złożonymi. Obiekt LinearLayout, który zawiera obiekty ImageView i TextView, działa bardziej efektywnie jako obiekt rysowalny złożony.
  • Scal ramkę główną. Jeśli katalog główny układu to FrameLayout, który nie zawiera tła ani dopełnienia, możesz zastąpić go tagiem kreatora e-maili, co jest trochę bardziej wydajne.
  • Usuń bezużyteczne liście. Aby uzyskać bardziej płaski i wydajną hierarchię układu, możesz usunąć układ, który nie ma elementów podrzędnych lub nie ma tła. Jest on niewidoczny.
  • Usuń bezużytecznych rodziców. Możesz usunąć układ z elementem podrzędnym, który nie ma elementów potomnych, nie ma układu ScrollView ani głównego i nie ma tła. Możesz też przenieść widok podrzędny bezpośrednio do elementu nadrzędnego, aby uzyskać bardziej płaską i wydajniejszą hierarchię układu.
  • Unikaj stosowania głębokich układów. Układy ze zbyt dużym zagnieżdżeniem obniżają wydajność. Rozważ użycie płaskich układów, np. ConstraintLayout, aby zwiększyć wydajność. Domyślna maksymalna głębokość sprawdzania lint to 10.

Inną zaletą narzędzia Lint jest integracja z Android Studio. Lint uruchamia się automatycznie przy skompilowaniu programu. W Android Studio możesz też przeprowadzić inspekcje lint dla konkretnej wersji kompilacji lub wszystkich jej wariantów.

Możesz też zarządzać profilami inspekcji i konfigurować inspekcji w Android Studio za pomocą opcji Plik > Ustawienia > Ustawienia projektu. Pojawi się strona Konfiguracja inspekcji z obsługiwanymi inspekcjami:

Ilustracja pokazująca menu inspekcji Android Studio
Rysunek 4. na stronie konfiguracji inspekcji.

Lint może automatycznie naprawiać niektóre problemy, wyświetlać sugestie innym i przejść bezpośrednio do kodu, który narusza zasady.

Więcej informacji znajdziesz na stronach o szablonach i zasobach Układów.