CarSettings UI 基础控件库

设计稿:

https://www.figma.com/file/jTWQPN2WJrJS23Xr9E3RVH/%E9%87%8F%E4%BA%A7-%E8%BD%A6%E8%BE%86%E8%AE%BE%E7%BD%AE?node-id=179%3A45424&t=CmWeEI3gEJFYQMJY-0

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:extLayoutTab下方扩展View的LayoutId

配置tab

CarUiTabLayout.Tab
属性说明
mText单个TabView的文案,不配置则不显示
mIconDrawableRes单个TabView的Icon资源Id,不配置则不显示
isAvailable配置单个TabView的enable状态
allowClickWhenDisabled配置单个TabView的disable时是否可点击
备注:现在micax的tabview disable时点击也会切换tab,等待新版本更新优化

配置button

CarUiTabLayout.Button
属性说明
mTextButton的文案,不配置则不显示
mIconDrawableResButton的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

BaseTabPreferenceController

SampleClass

ExteriorLightsTabLayPreferenceController

MiCarNewSwitchPreference @王洪强 Done

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

图例

支持的属性

属性说明
android:title主标题文案
android:summary副标题文案
settings:titleIcon主标题后面的icon
settings:rightIcon右侧icon
settings:rightText右侧文案
settings:upTitle上方的附加标题

点击事件

同BasicPreference

BaseController:

BaseVehicleNewSwitchPrefController

SampleClass

HighBeamAutoAdjustPrefController

SeekBarPreference @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中定义的自定义属性!

前后能量回收比例为例:

  1. 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>
  1. 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设置 内容View

PS:

  • 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" />