CarSettings UI 基础控件库
设计稿:
Preference
Preference 封装规范参考
建议大家再封装Preference的时候 layout里使用的id,采用通用的定义,参考如下:
- Title : android:R.id.title (PS:标题一定要用这个id,汽车问答会通过这个id查找控件)
- Summary: android:R.id.summary
- Icon: android:R.id.icon
micar ids.xml 自定义声明资源ID
- statusText: @string/micar_pref_status_text (如上边switch preference 右侧文案textview 使用的id)
- NavIcon: @string/micar_pref_nav_icon (如上边switch preference 右侧箭头imageview 使用的id)
- 其他 (可补充)
layout 、drawable等资源命名规则
-
统一前缀 micar_ui_xxx
如tab使用的layout: micar_ui_tab_xxx 如button使用的layout: micar_ui_button_xxx
-
preference引用的layout 统一前缀
micar_ui_pref_xxxx
其他规范可参考: CarSettings资源管理规范
PreferenceCategory: @王洪强 Done
- 标题
- 圆角背景

BasicPreference @王洪强 Done
📌 这个建议组件库提供封装,后续settings切换使用组件提供的switch preference, 需支持设定如下图示各种元素。
图例

支持的属性
| 属性 | 说明 |
|---|---|
| android:title | 主标题文案 |
| android:summary | 副标题文案 |
| android:icon | 左侧icon |
| settings:titleIcon | 主标题后面的icon |
| settings:rightIcon | 右侧icon |
| settings:rightText | 右侧文案 |
点击事件
public interface BasicPreferenceOnClickListener {
default void onTitleIconClicked() {
}
default void onRightIconClicked() {
}
default void onRightTextClicked() {
}
// 可替代preference的onClick
default void onPreferenceClicked() {
}
// preference的disable时点击回调
default void onPreferenceDisabledClicked() {
}
}拓展性
继承BasicPreference之后,在initPreference方法setWidgetLayoutResource可以扩展其它内容到下方:
override fun initPreference(
context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int
) {
super.initPreference(context, attrs, defStyleAttr, defStyleRes)
widgetLayoutResource = R.layout.layout_test
}ButtonTogglePreference(独立操作)@韩国良 Done


使用示例:
// in settings fragment preference.xml
<com.android.car.settings.miauto.preferences.ButtonTogglePreference
android:key="@string/pk_settings_vehicle_quick_ctrl_locks"
android:layout="@layout/micar_ui_pref_button_layout" //暂需要指定一下这个layout,后续提供默认
settings:controller="com.android.car.settings.miauto.vehicle.VehicleLockToggleCtrlPreferenceController"/>
// in controller 需要构造toggle button对应的数据,必要时重写该方法,示例是车控信号使用场景
public CarUiTabLayout.Button<VehicleQuickCtrl>[] getToggleButtons() {
List<CarUiTabLayout.Tab<VehicleQuickCtrl>> tmpButtonList = new ArrayList<>();
for (VehicleQuickCtrl ctrl: this.mSupportedCtrls) {
tmpButtonList.add(buildTabFromVehicleCtrl(ctrl));
}
CarUiTabLayout.Button<VehicleQuickCtrl>[] buttons = new CarUiTabLayout.Button[tmpButtonList.size()];
buttons = tmpButtonList.toArray(buttons);
return buttons;
}NewTabPreference(n选1 Tab + Button)@王洪强 Done
图例
基于BasicPreference的WidgetLayoutResource进行扩展,总体结构如下:

Title+Tab

Title+Summary+Tab+Button

Title+Tab+拓展View

支持的属性
BasicPreference所有属性+TabPerference专属属性
| 属性 | 说明 |
|---|---|
| settings:extLayout | Tab下方扩展View的LayoutId |
配置tab
CarUiTabLayout.Tab| 属性 | 说明 |
|---|---|
| mText | 单个TabView的文案,不配置则不显示 |
| mIconDrawableRes | 单个TabView的Icon资源Id,不配置则不显示 |
| isAvailable | 配置单个TabView的enable状态 |
| allowClickWhenDisabled | 配置单个TabView的disable时是否可点击 备注:现在micax的tabview disable时点击也会切换tab,等待新版本更新优化 |
配置button
CarUiTabLayout.Button| 属性 | 说明 |
|---|---|
| mText | Button的文案,不配置则不显示 |
| mIconDrawableRes | Button的Icon资源Id,不配置则不显示 |
| isAvailable | 配置Button的enable状态 |
| allowClickWhenDisabled | 配置Button的disable时是否可点击 |
| isCheckable | 是否可被选中 |
| hasIndicator | 是否显示右下角的小三角图标 |
| mIsSelected | 是否被高亮选中 |
| isProcessing | 是否为loading状态 |
回调事件
interface ITabCallback {
fun onSelectTabChanged(tab: Tab<*>)
fun onButtonClicked(button: Button<*>)
fun onBuildMiCarViewDescription(tab: Tab<*>): MiCarViewDescription?
fun onSelectedTabClicked(tab: Tab<*>) {}
fun onDisabledTabClicked(tab: Tab<*>) {}
}BaseController
BaseTabPreferenceControllerSampleClass
ExteriorLightsTabLayPreferenceControllerMiCarNewSwitchPreference @王洪强 Done
📌 这个建议组件库提供封装,后续settings切换使用组件提供的switch preference, 需支持设定如下图示各种元素。
图例

支持的属性
| 属性 | 说明 |
|---|---|
| android:title | 主标题文案 |
| android:summary | 副标题文案 |
| settings:titleIcon | 主标题后面的icon |
| settings:rightIcon | 右侧icon |
| settings:rightText | 右侧文案 |
| settings:upTitle | 上方的附加标题 |
点击事件
同BasicPreferenceBaseController:
BaseVehicleNewSwitchPrefControllerSampleClass
HighBeamAutoAdjustPrefControllerSeekBarPreference @Cookies 周家忻 Done
MiCarIconSeekBarPreference (滑块图例)
MiCarIconSeekBarPreference extends SeekBarPreference
样式举例

相关资源文件位置:
preference布局:micar_ui_pref_icon_seek_bar.xml:
自定义style:MiCarIconSeekBarStyle
使用方法
全局配置修改方法
原生对于原生SeekBar属性,在style.xml中的MiCarIconSeekBarStyle中指定即可。
此style中指定的属性对所有的MiCarIconSeekBarPreference生效。
自定义配置修改方法
自定义配置目前只支持attrs.xml中的MiCarIconSeekBar中定义的自定义属性!
以前后能量回收比例为例:
- styles_micar.xml中定义Style:MiCarIconSeekBarStyle.Driving
<!-- 如果设置到 Preference,仅对 MiCarIconSeekBar 的自定义属性有效 -->
<style name="MiCarIconSeekBarStyle.Driving" >
<item name="seekBarPadding">@dimen/micar_basic_dp_4</item>
</style>
<style name="MiCarIconSeekBarStyle.Driving.EnergyRecovery" >
<item name="leftIcon">@drawable/micar_driving_front_traction_ratio</item>
<item name="rightIcon">@drawable/micar_driving_rear_traction_ratio</item>
</style>- MiCarIconSeekBarPreference的属性中通过customStyle,指定刚刚自定义的style即
<com.android.car.settings.miauto.preferences.MiCarIconSeekBarPreference
android:key="@string/pk_settings_battle_energy_recovery"
android:title="@string/settings_battle_pref_title_energy_recovery"
settings:customStyle="@style/MiCarIconSeekBarStyle.Driving.EnergyRecovery"
settings:widgetLayout="@layout/seekbar_preference_action_button"
settings:controller="com.android.car.settings.miauto.battle.EnergyRecoveryPreferenceController"/>对于:N+1,通过widget指定即可。
滑动条图例
滑动条使用现有的SeekBarPreference

Edittext:右侧携带关闭按钮 @涂传涛 Done

控件类:com.android.micar.settings.ui.MiCarEditText
与普通EditText一样使用
Dialog @涂传涛 Done
3.1 普通AlertDialog:

AlertDialog dialog = new AlertDialog.Builder(getContext())
.setTitle("隐私权限限制")
.setMessage("打开“车内摄像头”允许“驾驶员疲劳提醒”使用车内摄像头权限")
.setPositiveButton("设置",
(dialogInterface, which) -> {
// do something
dialogInterface.dismiss();
})
.setNegativeButton("取消", null)
.create();
dialog.show();3.2 更改PostiveBtn 的样式

dialog.show();
MiCarSettingsExtKt.setDangerousPositiveBtnBg(dialog);PS:
- 一定要在 dialog.show()之后调用 MiCarSettingsExtKt.setDangerousPositiveBtnBg(dialog),否则获取不到 PositiveBtn;
- 使用的是 Micar中定义好的样式:android:backgroundTint=?attr/colorErrorSelector
3.3 自定义View的 AlertDialog:
3.3.1 EditText Dialog:

val view = LayoutInflater.from(mContext).inflate(R.layout.micar_ui_dialog_edit_text_layout, null)
mBuilder.setView(view) // 通过AlertBuilder设置 内容ViewPS:
- EditText Dialog 封装了一个hepler类: EdittextAlertDialogHelper
3.4 ContentDialog
图例:

实现方式1:使用DialogActivity
MiCarX 组件 使用说明(SOP) 详见micarx提供的DialogActivity
实现方式2:使用AlterDialog
代码+Layout(使用组件库的Toolbar)
abstract class BaseContentDialog{
protected abstract val mTitleResId: Int
protected abstract val mLayoutId: Int
// @IntDef(DIALOG_SIZE_SMALL, DIALOG_SIZE_MIDDLE, DIALOG_SIZE_BIG)
// 3种size的dialog
protected abstract val mDialogSizeStyle: Int
// true:导航键为关闭icon,false:导航键为返回icon
protected open val mIsNavigationClose: Boolean = true
// 是否初始化焦点,适用于使用按键调节后视镜、方向盘
protected open val mNeedInitFocus: Boolean = false
} <micarx.appcompat.widget.Toolbar
android:id="@+id/dialog_toolbar"
style="?attr/toolbarStyle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />