システムバーをカスタマイズする

システムバーをカスタマイズするには、XML 構成と Dagger モジュールを UI コンポーネントに組み合わせて使用します。

システムバーの動作を定義する

システムバーを定義するには、XML ファイルで <SystemBar> タグを使用して 外観とアニメーションを定義します。この XML ファイルは、ランタイム リソース オーバーレイ(RRO)の一部です。

SystemBar タグ属性

システムバー構成のルート要素は <SystemBar> で、 次の属性をサポートしています。

属性 ステータス 説明
id 必須 システムバーの一意のリソース ID。例: @id/my_custom_status_bar
type 必須 システムバーのタイプを指定します。 status または navigation のいずれかです。
barZOrder 必須

システムバーの Z オーダーを表す整数。値が大きいほど システムは他のバーの上にバーを描画します。正の 整数にする必要があります。次のルールが適用されます。

  • ヘッドアップ通知の上にシステムバーを表示する場合は、 この値を 10より大きくする必要があります。
  • 重複するシステムバーの Z オーダーを同じにすることはできません。
defaultVariant 必須 システムバーの初期化時にデフォルトで適用される <Variant> の ID
displayId 省略可 システムバーの初期化時にデフォルトで適用される <Variant> の ID
hideForKeyboard 省略可

ソフトウェア キーボードがアクティブなときにシステムバーが自動的に非表示になるかどうかを示すブール値(true または false)。この属性のデフォルト値は false です。

この属性が true の場合は、システムバーに _System_Show_Panel トランジションと _System_Hide_Panel トランジションを指定する必要があります。

dragOpenNotification 省略可

システムバーが通知パネルの自動オープンをトリガーするかどうかを示すブール値(true または false)。この属性のデフォルト値は false です。

dragCloseNotification 省略可

システムバーが通知パネルの自動クローズをトリガーするかどうかを示すブール値(true または false)。この属性のデフォルト値は false です。

システムバーの ID とタイプ

id 値として TopCarSystemBarBottomCarSystemBarLeftCarSystemBarRightCarSystemBar を使用しないでください。これらの ID は下位互換性のために予約されており、使用すると予期しない動作が発生する可能性があります。

基本的な上部ステータスバーと下部ナビゲーション バーの構成では、type 属性値としてそれぞれ statusnav を使用します。

これらの ID を使用する場合は、 Dagger でシステムバー UI を提供するのセクションをスキップできます。

<Variant>
視覚状態を定義します。詳しくは、バリアントを使用して 視覚状態を設計するをご覧ください。<SystemBar> タグで、1 つ以上の <Variant> タグを定義します。各バリアントは個別の視覚状態を表し、その状態でのシステムバーの外観を制御するプロパティが含まれています。
<Visibility isVisible="true|false">
システムバーの表示を制御します。isVisible ブール値は、システムバーが表示されているかどうかを示します。
<Alpha alpha="float_value">
システムバーの透明度を制御します。alpha の値は、0.0(完全に透明)から 1.0(完全に不透明)の間で変動します。
<Bounds .../>

システムバーの位置とサイズを定義します。<SystemBar> 要素の場合、 境界はディスプレイの少なくとも 1 つのエッジ(左、上、 右、下)に接触している必要があります。属性は次のとおりです。

  • 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 モジュールを作成する

カスタム レイアウト リソースを拡張するには、CarSystemBarViewSupplierUsingLayout クラスと CarSystemBarWindowSupplierUsingLayout クラスを使用します。

カスタム サプライヤを提供する Dagger モジュールを作成します。@StringKey は、 id XML タグの <SystemBar> と一致する必要があります。

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 文字列リソースは、プライバシー インジケーターをホストするシステムバーを指定します。値は id<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>

ドラッグ イベント リスナー

これらの構成では、ドラッグ イベントをリッスンするシステムバーを指定します(通知パネルを開くために下にスワイプするなど)。スケーラブル UI を搭載した Android Automotive OS 以降では、これらの機能を定義するために、駆動型検出リソース配列ではなく、デフォルトとして XML 属性を使用します。

推奨: XML 駆動型検出(スケーラブル UI)

オーバーレイ XML の <SystemBar> タグで dragOpenNotification 属性と dragCloseNotification 属性を直接使用します。

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

以前: リソース配列(フォールバック)

スケーラブル UI 以外のビルドを維持している場合や、下位互換性のあるデバイスのリスナーを指定する必要がある場合は、RRO の res/values/config.xml で従来の string-array アプローチを使用します。これらの 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 を含むフルビルドをフラッシュします。