如需自定义系统栏,请将 XML 配置和 Dagger 模块与界面组件结合使用。
定义系统栏行为
如需定义系统栏,请在 XML 文件中使用 <SystemBar> 标记来定义
外观和动画。此 XML 文件是运行时资源叠加层 (RRO) 的一部分。
SystemBar 标记属性
系统栏配置的根元素是 <SystemBar>,它支持
以下属性:
| 属性 | 状态 | 说明 |
|---|---|---|
id |
必需 | 系统栏的唯一资源 ID。例如,
@id/my_custom_status_bar |
type |
必需 | 指定系统栏的类型,可以是
status 或 navigation |
barZOrder |
必需 | 表示系统栏 Z 顺序的整数。值越大 表示系统在其他栏之上绘制该栏。必须是正 整数。适用以下规则:
|
defaultVariant |
必需 | 系统栏初始化时默认应用的 <Variant> 的 ID |
displayId |
可选 | 系统栏初始化时默认应用的 <Variant> 的 ID |
hideForKeyboard |
可选 |
布尔值 如果此属性为 |
dragOpenNotification |
可选 |
布尔值 |
dragCloseNotification |
可选 |
布尔值 |
系统栏 ID 和类型
避免使用 TopCarSystemBar、BottomCarSystemBar、LeftCarSystemBar 和 RightCarSystemBar 作为 id 值。系统保留这些 ID 以实现向后兼容性,使用这些 ID 可能会导致意外行为。
对于基本的顶部状态栏和底部导航栏配置,请分别使用 status 和 nav 作为 type 属性值。
如果您使用这些 ID,则可以跳过标题为 “使用 Dagger 提供系统栏界面”的部分。
<Variant>- 定义视觉状态。如需了解详情,请参阅使用变体
设计视觉状态。在
<SystemBar>标记中,定义一个或多个<Variant>标记。每个变体代表一个不同的视觉状态,并包含控制该状态下系统栏外观的属性。 <Visibility isVisible="true|false">- 控制系统栏的可见性。
isVisible布尔值用于指示系统栏是否可见。 <Alpha alpha="float_value">- 控制系统栏的透明度。
alpha的值介于0.0(完全透明)和1.0(完全不透明)之间。 <Bounds .../>定义系统栏的位置和大小。对于
<SystemBar>元素, 边界 必须 触及显示屏的至少一条边(左、上、 右或下)。属性包括:left、top、right、bottom:绝对坐标。width、height:尺寸。leftOffset、topOffset、rightOffset、bottomOffset:相对于矩形中心的偏移量。
<Corner radius="dimen"/>定义系统栏的圆角半径。对于
radius,请输入圆角半径的尺寸。<Insets .../>定义系统栏的内边距。属性包括
left、top、right和bottom。对于每个属性,请输入内边距的尺寸值。<Gravity .../>定义系统栏内容的重心。如需了解详情,请参阅源代码中的
HunTagXmlParserKt.GRAVITY_TAG。- 如果您省略了重心的值,系统会在内部计算该值。
- 支持的值是
TOP、BOTTOM、LEFT、RIGHT、CENTER、CENTER_HORIZONTAL、CENTER_VERTICAL和FILL_HORIZONTAL的组合, 每个值之间用|字符分隔。
尺寸单位
使用 px、dp(或 dip)、% 或对 dimension、integer、fraction、string 或 attribute 资源的引用来指定尺寸。
过渡:在变体之间添加动画效果
如需了解详情,请参阅配置转场。使用 <Transitions> 块定义系统栏在不同变体之间添加动画效果的方式:
| 推荐项 | 标记属性 |
|---|---|
<Transition> |
fromVariant、toVariant、onEvent、onEventTokens、animator、duration、delay、interpolator |
<Transitions> |
defaultDuration、defaultInterpolator |
只有在为非沉浸式模式用例定义过渡时,可缩放界面才支持系统栏中的过渡。这意味着,当沉浸式模式隐藏(或显示)系统栏时,不会触发系统栏的可缩放界面窗口过渡。
可缩放界面会继续发送用于隐藏(或显示)系统栏的事件,以便其他面板可以根据需要做出响应,同时必须提供用于隐藏和显示系统栏的过渡,以确保 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 提供系统栏界面
在 XML 中定义系统栏后,请提供实际的 View 和 Window。
为此,请将应用替换项应用于默认 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 在您的 <SystemBar> XML 标记中匹配。
如需替换 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 文件中设置多个影响系统栏的系统级配置。
停用旧版系统栏
为防止与可缩放界面发生冲突,请将以下标志设置为 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>
拖动事件监听器
这些配置用于指定哪些系统栏监听拖动事件(例如,向下滑动以打开通知面板)。从搭载可缩放界面的 Android Automotive OS 开始,请使用 XML 属性作为默认值,而不是使用驱动发现资源数组来定义这些功能。
推荐:XML 驱动的发现(可缩放界面)
直接在叠加层 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>
旧版:资源数组(回退)
如果您要维护非可缩放界面 build,或者需要为向后兼容的设备指定监听器,请在 RRO 的 res/values/config.xml 中使用旧版 string-array 方法。这些 string-array 资源用于指定哪些系统栏监听拖动事件。例如,打开通知面板。每个 <item> 都是系统栏的 id 名称。
config_registerHvacDragCloseListenerconfig_notificationDragOpenListenerconfig_notificationDragCloseListener
例如:
<resources>
<string-array name="config_notificationDragOpenListener" translatable="false">
<item>my_custom_status_bar</item>
</string-array>
</resources>
构建和部署
如需构建和部署状态栏,请执行以下操作:
使用修改后的 SystemUI 替换应用刷写设备。
使用 Android 构建系统 (
m) 编译 RRO 项目。将生成的 RRO APK 部署到 Android Automotive 设备。使用
adb install或刷写包含 RRO 的完整 build。