Dostosowywanie pasków systemu

Aby dostosować paski systemowe, użyj kombinacji konfiguracji XML i modułów Dagger do komponentów interfejsu.

Określanie zachowania paska systemowego

Aby zdefiniować pasek systemowy, użyj tagu <SystemBar> w pliku XML, aby określić wygląd i animację. Ten plik XML jest częścią nakładki zasobów środowiska wykonawczego (RRO).

Atrybuty tagu SystemBar

Elementem głównym konfiguracji paska systemowego jest <SystemBar>, który obsługuje te atrybuty:

Atrybut Stan Opis
id Wymagane Unikalny identyfikator zasobu paska systemowego. Na przykład @id/my_custom_status_bar
type Wymagane Określa typ paska systemowego, który może być status lub navigation
barZOrder Wymagane

Liczba całkowita reprezentująca kolejność Z paska systemowego. Wyższe wartości oznaczają, że system rysuje pasek na wierzchu innych. Musi to być dodatnia liczba całkowita. Obowiązują te reguły:

  • Jeśli wyświetlasz pasek systemowy nad powiadomieniem heads-up, to ta wartość musi być większa niż 10
  • Nakładające się paski systemowe nie mogą mieć tej samej kolejności Z.
defaultVariant Wymagane Identyfikator <Variant>, który jest domyślnie stosowany podczas inicjowania paska systemowego.
displayId Opcjonalnie Identyfikator <Variant>, który jest domyślnie stosowany podczas inicjowania paska systemowego.
hideForKeyboard Opcjonalnie

Wartość logiczna true lub false wskazująca, czy pasek systemowy ma być automatycznie ukrywany, gdy aktywna jest klawiatura programowa. Domyślna wartość tego atrybutu to false.

Gdy ten atrybut ma wartość true, musisz podać _System_Show_Panel i _System_Hide_Panel przejścia dla paska systemowego.

dragOpenNotification Opcjonalnie

Wartość logiczna true lub false wskazująca czy pasek systemowy ma automatycznie wywoływać otwarcie panelu powiadomień. Domyślna wartość tego atrybutu to false.

dragCloseNotification Opcjonalnie

Wartość logiczna true lub false wskazująca czy pasek systemowy ma automatycznie wywoływać zamknięcie panelu powiadomień. Domyślna wartość tego atrybutu to false.

Identyfikatory i typy pasków systemowych

Unikaj używania TopCarSystemBar, BottomCarSystemBar, LeftCarSystemBar i RightCarSystemBar jako wartości id. System rezerwuje te identyfikatory na potrzeby zgodności wstecznej, a ich użycie może prowadzić do nieoczekiwanego zachowania.

W przypadku podstawowych konfiguracji górnego paska stanu i dolnego paska nawigacyjnego użyj odpowiednio wartości status i nav jako wartości atrybutu type.

Jeśli używasz tych identyfikatorów, możesz pominąć sekcję zatytułowaną Udostępnianie interfejsu paska systemowego za pomocą Dagger.

<Variant>
Określa stany wizualne. Więcej informacji znajdziesz w artykule Używanie wariantu do projektowania stanu wizualnego. W tagu <SystemBar> zdefiniuj co najmniej 1 <Variant> tagów. Każdy wariant reprezentuje odrębny stan wizualny i zawiera właściwości, które kontrolują wygląd paska systemowego w tym stanie.
<Visibility isVisible="true|false">
Kontroluje widoczność paska systemowego. Wartość logiczna isVisible wskazuje, czy pasek systemowy jest widoczny.
<Alpha alpha="float_value">
Kontroluje przezroczystość paska systemowego. Wartość alpha mieści się w zakresie od 0.0 (pełna przezroczystość) do 1.0 (pełna nieprzezroczystość).
<Bounds .../>

Określa położenie i rozmiar paska systemowego. W przypadku elementów <SystemBar> granice muszą dotykać co najmniej jednej krawędzi wyświetlacza (lewej, górnej, prawej lub dolnej). Atrybuty:

  • left, top, right, bottom: współrzędne bezwzględne.
  • width, height: wymiary.
  • leftOffset, topOffset, rightOffset, bottomOffset: przesunięcia w kierunku środka prostokąta.
<Corner radius="dimen"/>

Określa promień narożnika paska systemowego. W przypadku radius wpisz wymiar promienia narożnika.

<Insets .../>

Określa wcięcia paska systemowego. Atrybuty to left, top, right i bottom. W przypadku każdego atrybutu wpisz wartość wymiaru wcięć.

<Gravity .../>

Określa położenie treści paska systemowego. Więcej informacji znajdziesz w kodzie źródłowym w HunTagXmlParserKt.GRAVITY_TAG.

  • Jeśli pominiesz wartość położenia, system obliczy ją wewnętrznie.
  • Obsługiwane wartości to kombinacje TOP, BOTTOM, LEFT, RIGHT, CENTER, CENTER_HORIZONTAL, CENTER_VERTICAL i FILL_HORIZONTAL, z których każda jest oddzielona znakiem |.

Jednostki wymiarów

Wymiary określaj za pomocą px, dp (lub dip), % albo odwołań do zasobów dimension, integer, fraction, string lub attribute.

Przejścia: animowanie między wariantami

Więcej informacji znajdziesz w artykule Konfigurowanie przejścia. Użyj bloku <Transitions>, aby określić, jak pasek systemowy ma animować między różnymi wariantami:

Element Atrybut tagu
<Transition> fromVariant, toVariant, onEvent, onEventTokens, animator, duration, delay, interpolator
<Transitions> defaultDuration, defaultInterpolator

Skalowalny interfejs użytkownika obsługuje przejścia na paskach systemowych tylko wtedy, gdy zdefiniujesz je na potrzeby przypadków użycia w trybie niepełnoekranowym. Oznacza to, że tryb pełnoekranowy nie wywołuje przejść okien skalowalnego interfejsu użytkownika na paskach systemowych, gdy ukrywa (lub wyświetla) pasek systemowy.

Skalowalny interfejs użytkownika nadal wysyła zdarzenia ukrywania (lub wyświetlania) paska systemowego, aby inne panele mogły w razie potrzeby reagować. Aby atrybut hideForKeyboard działał prawidłowo, musisz podać przejścia ukrywania i wyświetlania pasków systemowych. Oto przykładowa struktura XML:

<SystemBar id="@id/my_custom_status_bar" type="status" barZOrder="0" defaultVariant="@id/default_variant" hideForKeyboard="true">
    <Variant id="@+id/default_variant">
        <Bounds top="0px" left="0px" right="100%" height="100px"/>
        <Visibility isVisible="true"/>
    </Variant>
    <Variant id="@+id/hidden_variant" parent="@id/default_variant">
        <Visibility isVisible="false"/>
    </Variant>
    <Transitions>
        <Transition onEvent="_System_Show_Panel" onEventTokens="panelId= my_custom_status_bar" toVariant="@id/default_variant"/>
        <Transition onEvent="_System_Hide_Panel" onEventTokens="panelId= my_custom_status_bar" toVariant="@id/hidden_variant"/>
    </Transitions>
</SystemBar>

Udostępnianie interfejsu paska systemowego za pomocą Dagger

Po zdefiniowaniu paska systemowego w XML podaj rzeczywisty View i Window. Aby to zrobić, zastosuj zastąpienie aplikacji do domyślnego modułu Dagger, CarSystemBarModule.java. Przykład:

import com.android.systemui.car.systembar.CarSystemBarViewSupplier;
import com.android.systemui.car.systembar.CarSystemBarWindowSupplier;
import com.android.systemui.car.systembar.CarSystemBarWindowSupplierUsingLayout;
import com.example.R;

import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import dagger.multibindings.StringKey;

@Module
public abstract class MySystemBarModule extends CarSystemBarModule {

    @Provides
    @IntoMap
    @StringKey("my_custom_status_bar") // Matches the <SystemBar> id
    static CarSystemBarViewSupplier bindMyCustomStatusBarViewSupplier() {
        return new CarSystemBarViewSupplierUsingLayout(
            R.layout.my_custom_status_bar, // provisioned layout
            R.layout.my_custom_status_bar_unprovisioned // unprovisioned layout
        );
    }

    @Provides
    @IntoMap
    @StringKey("my_custom_status_bar") // Matches the <SystemBar> id
    static CarSystemBarWindowSupplier bindMyCustomStatusBarWindowSupplier() {
        return new CarSystemBarWindowSupplierUsingLayout(
            R.layout.my_navigation_bar_window, // Can reuse existing window layouts
            R.id.my_custom_bar_window // The ID that will be assigned to the window
        );
    }
}

Tworzenie modułu Dagger w zastąpieniu SystemUI

Aby rozwinąć niestandardowe zasoby układu, użyj klas CarSystemBarViewSupplierUsingLayout i CarSystemBarWindowSupplierUsingLayout.

Utwórz moduł Dagger, aby udostępnić niestandardowych dostawców. @StringKey musi być zgodny z id w tagu XML <SystemBar>.

Aby zastąpić CarSystemBarModule, zobacz ten przykładowy kod:

import com.android.systemui.car.systembar.CarSystemBarViewSupplier;
import com.android.systemui.car.systembar.CarSystemBarWindowSupplier;
import com.android.systemui.car.systembar.CarSystemBarWindowSupplierUsingLayout;
import com.example.R;

import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import dagger.multibindings.StringKey;

@Module
public abstract class MySystemBarModule extends CarSystemBarModule {

    @Provides
    @IntoMap
    @StringKey("my_custom_status_bar") // Matches the <SystemBar> id
    static CarSystemBarViewSupplier bindMyCustomStatusBarViewSupplier() {
        return new CarSystemBarViewSupplierUsingLayout(
            R.layout.my_custom_status_bar, // provisioned layout
            R.layout.my_custom_status_bar_unprovisioned // unprovisioned layout
        );
    }

    @Provides
    @IntoMap
    @StringKey("my_custom_status_bar") // Matches the <SystemBar> id
    static CarSystemBarWindowSupplier bindMyCustomStatusBarWindowSupplier() {
        return new CarSystemBarWindowSupplierUsingLayout(
            R.layout.my_navigation_bar_window, // Can reuse existing window layouts
            R.id.my_custom_bar_window // The ID that will be assigned to the window
        );
    }
}

Tworzenie konfiguracji na poziomie systemu za pomocą RRO

Ustaw kilka konfiguracji na poziomie systemu, które wpływają na paski systemowe, w pliku res/values/config.xml w RRO.

Wyłączanie starszych pasków systemowych

Aby uniknąć konfliktów ze skalowalnym interfejsem użytkownika, wyłącz konfiguracje starszych pasków systemowych, ustawiając te flagi na false:

<resources>
    <bool name="config_enableTopSystemBar">false</bool>
    <bool name="config_enableBottomSystemBar">false</bool>
    <bool name="config_enableLeftSystemBar">false</bool>
    <bool name="config_enableRightSystemBar">false</bool>
</resources>

Lokalizacja wskaźnika prywatności

Zasób tekstowy config_privacyIndicatorLocation określa, który pasek systemowy ma zawierać wskaźniki prywatności. Wartość musi być nazwą id elementu <SystemBar>.

<resources>
    <!-- "my_custom_status_bar" corresponds to the android:id name of a SystemBar -->
    <string name="config_privacyIndicatorLocation">my_custom_status_bar</string>
</resources>

Detektory zdarzeń przeciągnięcia

Te konfiguracje określają, które paski systemowe mają nasłuchiwać zdarzeń przeciągnięcia (np. aby otworzyć panel powiadomień przez przesunięcie palcem w dół). W systemie operacyjnym Android Automotive ze skalowalnym interfejsem użytkownika do określania tych funkcji używaj atrybutów XML jako domyślnych zamiast tablic zasobów wykrywania sterowanego.

Zalecane: wykrywanie sterowane przez XML (skalowalny interfejs użytkownika)

Użyj atrybutów dragOpenNotification i dragCloseNotification bezpośrednio w tagu <SystemBar> w nakładce XML:

<SystemBar id="@id/my_custom_status_bar" type="status" barZOrder="0" defaultVariant="@id/default_variant" dragOpenNotification="true">
    <Variant id="@+id/default_variant">
        <Bounds top="0px" left="0px" right="100%" height="100px"/>
        <Visibility isVisible="true"/>
    </Variant>
</SystemBar>

Starsza wersja: tablica zasobów (rezerwowa)

Jeśli utrzymujesz kompilację bez skalowalnego interfejsu użytkownika lub musisz określić detektory dla urządzeń zgodnych wstecznie, użyj starszego podejścia string-array w res/values/config.xml w RRO. Te zasoby string-array określają, które paski systemowe mają nasłuchiwać zdarzeń przeciągnięcia. Na przykład aby otworzyć panel powiadomień. Każdy <item> to nazwa id paska systemowego.

  • config_registerHvacDragCloseListener
  • config_notificationDragOpenListener
  • config_notificationDragCloseListener

Przykład:

<resources>
    <string-array name="config_notificationDragOpenListener" translatable="false">
        <item>my_custom_status_bar</item>
    </string-array>
</resources>

Kompilowanie i wdrażanie

Aby skompilować i wdrożyć pasek stanu:

  1. Sflashuj urządzenie zmodyfikowaną aplikacją zastępującą SystemUI.

  2. Użyj systemu kompilacji Androida (m), aby skompilować projekt RRO.

  3. Wdróż wygenerowany plik APK RRO na urządzeniu z Androidem Automotive. Użyj adb install lub sflashuj pełną kompilację, która zawiera RRO.