自訂系統資訊列

如要自訂系統資訊列,請搭配使用 XML 設定和 Dagger 模組,設定 UI 元件。

定義系統資訊列行為

如要定義系統資訊列,請在 XML 檔案中使用 <SystemBar> 標記定義外觀和動畫。這個 XML 檔案是執行階段資源覆蓋 (RRO) 的一部分。

SystemBar 標記屬性

系統資訊列設定的根元素為 <SystemBar>,支援下列屬性:

屬性 狀態 說明
id 必填 系統資訊列的不重複資源 ID。例如: @id/my_custom_status_bar
type 必填 指定系統資訊列類型,可以是 statusnavigation
barZOrder 必填

代表系統資訊列 Z 順序的整數。值越大,表示系統會將該長條繪製在其他長條上方。必須是正整數。規則如下:

  • 如果您在抬頭通知上方顯示系統資訊列,則這個值必須大於 10
  • 重疊的系統資訊列不得具有相同的 Z 順序
defaultVariant 必填 系統初始化系統資訊列時,預設套用的 <Variant> ID
displayId 選用 系統初始化系統資訊列時,預設套用的 <Variant> ID
hideForKeyboard 選用

布林值為 truefalse,表示螢幕鍵盤啟用時,系統資訊列是否會自動隱藏。此屬性預設為 false

如果這項屬性為 true,則必須提供系統資訊列的 _System_Show_Panel_System_Hide_Panel 轉場效果。

dragOpenNotification 選用

truefalse 的布林值,表示系統資訊列是否會自動觸發開啟通知面板。此屬性預設為 false

dragCloseNotification 選用

truefalse 的布林值,表示系統資訊列是否會自動觸發關閉通知面板。此屬性預設為 false

系統資訊列 ID 和類型

請避免使用 TopCarSystemBarBottomCarSystemBarLeftCarSystemBarRightCarSystemBar 做為 id 值。系統會保留這些 ID,以確保回溯相容性,使用這些 ID 可能會導致非預期行為。

如要設定基本的頂端狀態列和底部導覽列,請分別使用 statusnav 做為 type 屬性值。

如果您使用這些 ID,可以略過「使用 Dagger 提供系統資訊列 UI」一節。

<Variant>
定義視覺狀態。詳情請參閱「使用變體設計視覺狀態」。在 <SystemBar> 標記中,定義一或多個 <Variant> 標記。每個變體代表不同的視覺狀態,並包含控制該狀態下系統資訊列外觀的屬性。
<Visibility isVisible="true|false">
控制系統資訊列的顯示設定。isVisible 布林值會指出系統資訊列是否顯示。
<Alpha alpha="float_value">
控制系統資訊列的透明度。alpha 的值介於 0.0 (完全透明) 和 1.0 (完全不透明) 之間。
<Bounds .../>

定義系統資訊列的位置和大小。如果是 <SystemBar> 元素,邊界必須觸及螢幕的至少一個邊緣 (左、上、右或下)。屬性包括:

  • lefttoprightbottom:絕對座標。
  • widthheight:維度。
  • leftOffsettopOffsetrightOffsetbottomOffset:矩形中心的偏移量。
<Corner radius="dimen"/>

定義系統資訊列的圓角半徑。在 radius 中,輸入圓角半徑的維度。

<Insets .../>

定義系統資訊列的插邊。屬性為 lefttoprightbottom。針對每個屬性,輸入插邊的維度值。

<Gravity .../>

定義系統資訊列內容的重力。詳情請參閱原始碼中的 HunTagXmlParserKt.GRAVITY_TAG

  • 如果省略重力值,系統會在內部計算。
  • 支援的值為 TOPBOTTOMLEFTRIGHTCENTERCENTER_HORIZONTALCENTER_VERTICALFILL_HORIZONTAL 的組合,每個值之間以 | 字元分隔。

尺寸單位

使用 pxdp (或 dip)、% 或參照 dimensionintegerfractionstringattribute 資源,指定維度。

轉場效果:在變體之間加入動畫

詳情請參閱「設定轉場效果」。使用 <Transitions> 區塊定義系統資訊列在不同變化版本間的動畫效果:

項目 標記屬性
<Transition> fromVarianttoVariantonEventonEventTokensanimatordurationdelayinterpolator
<Transitions> defaultDurationdefaultInterpolator

只有在為非沉浸模式用途定義轉場效果時,可調整大小的 UI 才會支援系統資訊列中的轉場效果。也就是說,當隱藏 (或顯示) 系統資訊列時,沉浸模式不會觸發系統資訊列的可縮放 UI 視窗轉換。

可調整大小的 UI 會繼續傳送隱藏 (或顯示) 系統資訊列的事件,以便其他面板視需要做出回應,同時必須提供隱藏和顯示系統資訊列的轉場效果,才能讓 hideForKeyboard 屬性正常運作。請參考以下 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>

使用 Dagger 提供系統資訊列 UI

在 XML 中定義系統資訊列後,請提供實際的 ViewWindow。 如要這麼做,請將應用程式覆寫套用至預設 Dagger 模組,CarSystemBarModule.java例如:

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
        );
    }
}

在 SystemUI 覆寫中建立 Dagger 模組

如要擴充自訂版面配置資源,請使用 CarSystemBarViewSupplierUsingLayoutCarSystemBarWindowSupplierUsingLayout 類別。

建立 Dagger 模組,提供自訂供應商。@StringKey 必須與 <SystemBar> XML 標記中的 id 相符。

如要覆寫 CarSystemBarModule,請參閱下列程式碼範例:

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
        );
    }
}

使用 RRO 建立系統層級設定

在 RRO 的 res/values/config.xml 檔案中,設定多個影響系統資訊列的系統層級設定。

停用舊版系統資訊列

為避免與可調整大小的 UI 發生衝突,請將下列標記設為 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>

隱私權指標位置

config_privacyIndicatorLocation 字串資源會指定哪個系統資訊列代管隱私權指標。這個值必須是 <SystemBar>id 名稱。

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

拖曳事件監聽器

這些設定會指定哪些系統資訊列會監聽拖曳事件 (例如向下滑動開啟通知面板)。在 Android Automotive OS (可調整大小的 UI) 中,請使用 XML 屬性做為預設值,而非驅動探索資源陣列,定義這些功能。

建議:XML 驅動的探索 (可擴充的 UI)

在疊加層 XML 的 <SystemBar> 標記中,直接使用 dragOpenNotificationdragCloseNotification 屬性:

<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>

舊版:資源陣列 (備用)

如果您要維護非可調整大小的使用者介面建構版本,或需要為回溯相容裝置指定監聽器,請在 RRO 中使用舊版 string-array 方法 res/values/config.xml。這些 string-array 資源會指定哪些系統資訊列監聽拖曳事件。舉例來說,開啟通知面板。每個 <item> 都是系統資訊列的 id 名稱。

  • config_registerHvacDragCloseListener
  • config_notificationDragOpenListener
  • config_notificationDragCloseListener

例如:

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

建構及部署

如要建構及部署狀態列:

  1. 使用修改後的 SystemUI 覆寫應用程式刷新裝置。

  2. 使用 Android 建構系統 (m) 編譯 RRO 專案。

  3. 將產生的 RRO APK 部署至 Android Automotive 裝置。使用 adb install 或刷入包含 RRO 的完整版本。