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 sekcji Utwórz

Często panuje błędne przekonanie, że używanie podstawowych struktur układu pozwala uzyskać najefektywniejszy układ. Jednak każdy widżet i układ, który dodasz do aplikacji, wymaga inicjowania, układu i rysowania. Na przykład używanie zagnieżdżonych instancji funkcji LinearLayout może prowadzić do nadmiernie szczegółowej hierarchii widoków. Poza tym zagnieżdżenie kilku wystąpień LinearLayout, które korzystają z parametru layout_weight, może być szczególnie kosztowne, ponieważ każdy element podrzędny musi być zmierzony dwa razy. Jest to szczególnie ważne, gdy układ jest wielokrotnie zwiększany, np. gdy jest używany w elemencie RecyclerView.

W tym dokumencie opisujemy, jak badać i optymalizować układ za pomocą Inspektora układu i lintowania.

Sprawdzanie układu

Narzędzia pakietu Android SDK zawierają narzędzie Inspektor układu, które umożliwia analizowanie układu podczas działania aplikacji. Korzystanie z tego narzędzia pomaga wykrywać nieefektywność układu.

Inspektor układu pozwala wybrać procesy uruchomione na połączonym urządzeniu lub emulatorze, a następnie wyświetlić drzewo układu. Sygnalizacja świetlna na każdym bloku sygnalizuje skuteczność funkcji Measure, Układ i Rysuj, by pomóc w wykrywaniu potencjalnych problemów.

Na przykład rys. 1 pokazuje układ używany jako element w elemencie RecyclerView. W tym układzie po lewej stronie wyświetla się mały obraz bitmapy, a po prawej 2 ułożone na siebie elementy tekstu. Szczególnie ważne jest, aby takie układy, które są wielokrotnie rozszerzane, były optymalizowane, ponieważ mnożą się korzyści związane ze skutecznością.

Grafika przedstawiająca jeden element na liście: 1 obraz i 2 teksty w pionie
Rysunek 1. Układ koncepcyjny elementu w: RecyclerView.

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

Obraz przedstawiający Inspektora układu i kompozycję układu linearnego
Rysunek 2. Hierarchia układu dla układu przedstawionego na Rysunku 1 z zagnieżdżonymi wystąpieniami funkcji LinearLayout.

Zmiana układu

Ponieważ wydajność poprzedniego układu spada z powodu zagnieżdżonego tagu LinearLayout, można poprawić wydajność, tworząc płaski układ, czyli tworząc płytki i szeroki, a nie wąski i głębokim układ. ConstraintLayout, jako węzeł główny zezwala na stosowanie takich układów. Gdy przekonwertujesz ten projekt na ConstraintLayout, układ zmieni się w 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>
    

Sprawdzanie nowego układu wygląda tak:

Obraz przedstawiający Inspektor układu 3D
Rysunek 3. Tryb 3D Inspektora układu.

Korzyści są mnożone, bo taki układ jest stosowany do każdego elementu na liście.

Większość różnic wynika z użycia elementu layout_weight w strukturze LinearLayout, co może spowolnić pomiar. To przykład zastosowania każdego układu. Zastanów się, czy nie warto używać wagi układu.

W niektórych złożonych układach system może tracić nakład pracy na pomiar tego samego elementu interfejsu więcej niż raz. Zjawisko to nazywane jest podwójnym opodatkowaniem. Więcej informacji o podwójnym opodatkowaniu i o tym, jak mu zapobiegać, znajdziesz w artykule Skuteczność i widoki hierarchii.

Użyj linter

Warto w plikach układu uruchomić narzędzie lint, aby wyszukać możliwe optymalizacje hierarchii widoków. Lint zastępuje narzędzie do Układu i zapewnia większą funkcjonalność. Oto przykłady reguł lintowania:

  • Użyj elementów rysowanych składanych. Obiekty LinearLayout, które zawierają elementy ImageView i TextView, możesz obsługiwać efektywniej jako obiekt rysowalny.
  • Scalanie ramki głównej. Jeśli katalogiem głównym układu jest FrameLayout, który nie ma tła ani dopełnienia, możesz zastąpić go tagiem kreatora e-maili, co jest nieco bardziej skuteczne.
  • Usuń bezużyteczne liście. Aby uzyskać bardziej płaską i efektywną hierarchię układu, możesz usunąć układ, który nie ma elementów podrzędnych lub nie ma tła, ponieważ jest niewidoczny.
  • Usuń bezużytecznych rodziców. Możesz usunąć układ z elementem podrzędnym, który nie ma elementów równorzędnych, nie jest układem ScrollView ani głównym oraz nie ma tła. Widok podrzędny możesz też przenieść bezpośrednio do widoku nadrzędnego, by uzyskać bardziej płaski i wydajny układ.
  • Unikaj głębokich układów. Układy ze zbyt obszernym zagnieżdżeniem mają negatywny wpływ na wydajność. Rozważ użycie bardziej płaskich układów, np. ConstraintLayout, aby zwiększyć skuteczność. Domyślna maksymalna głębokość sprawdzania linterów to 10.

Kolejną zaletą narzędzia Lint jest integracja z Androidem Studio. Lint uruchamia się automatycznie przy każdej kompilacji programu. W Android Studio możesz też przeprowadzać inspekcje lintowania konkretnych wersji kompilacji lub wszystkich jej wariantów.

Profile inspekcji i inspekcji możesz też zarządzać w Android Studio po wybraniu opcji Plik > Ustawienia > Ustawienia projektu. Pojawi się strona Konfiguracja inspekcji z obsługiwanymi inspekcjami:

Obraz przedstawiający menu narzędzia inspekcji Android Studio
Rysunek 4. Strona konfiguracji inspekcji.

Lint może automatycznie naprawiać niektóre problemy, przekazywać sugestie innym, a także przejść bezpośrednio do kodu naruszającego zasady w celu sprawdzenia.

Więcej informacji znajdziesz w sekcji dotyczącej Układów i Zasobów układu.