01 · 类体系与模块分工
基线:MiCarSupport @ dev
52a51649(micarx 3.2.8)。 MAT =material/src/main/java/com/mi/car/material/slider/, ABW =androidbasewidget/src/main/java/micarx/androidbasewidget/, PREF =preference/src/main/java/micarx/preference/。
1. 全局地图:三套互不同源的滑块实现
flowchart TB subgraph MaterialFork["float 值域体系(fork 自 Google Material Slider)"] BaseSlider["BaseSlider<S,L,T> (abstract)<br/>MAT/BaseSlider.java:211<br/>3297 行,全部手势/绘制核心"] Slider["Slider<br/>MAT/Slider.java:50<br/>单值定版 + SliderAnimation"] IconSlider["IconSlider<br/>ABW/IconSlider.java:34<br/>thumb 文字/图标 + 自研按压动画"] PlayerProgressbar["PlayerProgressbar<br/>appcompat/.../player/PlayerProgressbar.java:21<br/>播放进度"] end subgraph SeekBarFamily["int progress 体系(原生 SeekBar 生态)"] AppCompatSeekBarX["micarx.appcompat.widget.AppCompatSeekBar<br/>MAT/micarx/appcompat/widget/AppCompatSeekBar.java:29<br/>主题 clip + 按压动画 + ignoreClick"] IconSeekBar["IconSeekBar<br/>ABW/IconSeekBar.java:35<br/>thumb 文字/图标 + 双组按压动画"] LegacySeekBar["ABW SeekBar (已废弃)<br/>ABW/SeekBar.java:15 @Deprecated<br/>零引用,仅画前导 icon"] end subgraph Vertical["垂直体系(独立自绘)"] VerticalSlider["VerticalSlider<br/>ABW/VerticalSlider.java:45<br/>extends View,拷贝 BaseSlider 骨架"] end BaseSlider -->|extends View| ViewA["android.view.View"] Slider --> BaseSlider IconSlider --> Slider PlayerProgressbar --> Slider AppCompatSeekBarX -->|extends| AndroidxSB["androidx.appcompat.widget.AppCompatSeekBar"] IconSeekBar --> AppCompatSeekBarX LegacySeekBar -->|extends(注意:不是 micarx 版)| AndroidxSB VerticalSlider -->|extends View(不继承 BaseSlider)| ViewB["android.view.View"] style BaseSlider fill:#ffe1e1 style AppCompatSeekBarX fill:#ffe1e1 style VerticalSlider fill:#e1f0ff
铁律:IconSlider 与 BaseSlider 是继承关系,不是包装;IconSeekBar 与 BaseSlider 族 零共享代码。两族的主题 delegate 也是两套独立接口(见 03 篇)。
2. 三模块分工
| 模块 | 角色 | 关键类 | 特征 |
|---|---|---|---|
| material | 基础滑杆 + 主题 delegate 接口 | BaseSlider/Slider、SliderThemeDelegate、SeekBarThemeDelegate、micarx AppCompatSeekBar | float 值域、stepSize 吸附、TooltipDrawable label |
| androidbasewidget | 车机定制壳(thumb 文字/图标/按压动画) | IconSlider、IconSeekBar、VerticalSlider、*IconSliderThemeDelegate | 在 material 之上加 thumb 内容绘制与 Folme 弹簧动画 |
| preference | 设置项封装(Settings 未使用) | SeekBarPreference、SliderPreference、SeekBarPreferenceCompat | 详见 05 篇 |
3. 选型矩阵(什么场景用哪个)
| 需求 | 选型 | 实证 |
|---|---|---|
| 纯滑杆(如播放进度) | material Slider | MiCarSettings micarMedia VideoPlayerActivity + exo_player_control_view.xml:91 |
| thumb 带当前值/图标、两端文案、float 生态 | IconSlider | 能量回收/限速弹窗(Settings 经 MiCarIconSlider 包装) |
| 同上但 int/SeekBar 生态 | IconSeekBar | 车门高度、音量(Settings 经 MiCarIconSeekBar 包装) |
| 垂直调节(屏幕俯仰角) | VerticalSlider | catalog VerticalSliderActivity;Settings 后屏角度 |
| 裸 SeekBar preference | 组件库 SeekBarPreference(绑框架 SeekBar) | Settings 未使用,Settings 全部走自建 settingsBaseUi 体系 |
Settings 侧完整使用地图见 05 篇 §7。
4. 主题 delegate 策略模式总览
flowchart LR ThemeAttr["theme attr<br/>micarxThemeStyleName"] --> Factory["静态工厂 create()"] Factory --> Normal["NormalXxxThemeDelegate<br/>原样直通/no-op 为主"] Factory --> GT["GtXxxThemeDelegate<br/>竖条 thumb + 点击抑制 + 扩张动画"] Factory --> Ultra["UltraXxxThemeDelegate<br/>与 GT 逐行相同(预留独立演进)"] subgraph ThreeSets["三套独立 delegate 接口(互不继承)"] S1["SliderThemeDelegate (MAT)<br/>服务 BaseSlider/Slider"] S2["IconSliderThemeDelegate (ABW)<br/>服务 IconSlider"] S3["SeekBarThemeDelegate (MAT)<br/>服务 AppCompatSeekBar + IconSeekBar"] S4["VerticalSliderThemeDelegate (ABW)<br/>服务 VerticalSlider,仅 3 方法"] end Factory -.分派.-> ThreeSets
- 主题来源:
ThemeStyleUtil.getThemeNameFromAttr(context, micarxThemeStyleName)(BaseSlider.java:591-592、IconSlider 经 BaseSlider 构造、IconSeekBar.java:125、 VerticalSlider.java:152-156)。 - 一个 IconSlider 实例内部同时存在两个 delegate:BaseSlider 构造创建的
mThemeDelegate(SliderThemeDelegate,管轨道几何/padding)+ IconSlider 自建的mIconSliderThemeDelegate(IconSliderThemeDelegate,管图标/文字/按压/点击抑制)。 IconSeekBar 同理有两份SeekBarThemeDelegate实例(父类 AppCompatSeekBar:87 一份, IconSeekBar:125 一份,遮蔽父类字段,各管各的绘制)。 - GT 与 Ultra 的四个 delegate 实现均逐行相同,注释声明 “Separate from GtXxx for independent extensibility”(如 UltraSliderThemeDelegate.java:9-13)——改 GT 行为时 务必检查 Ultra 是否要同步。
5. 值模型差异(两个世界的分水岭)
| 维度 | Slider 族(BaseSlider) | SeekBar 族(IconSeekBar) |
|---|---|---|
| 值类型 | float values[](多 thumb 能力,单 thumb 取 [0]) | int progress(ProgressBar) |
| 范围 | valueFrom/valueTo | min/max(IconSeekBar 校验 max≠min 否则 IAE,IconSeekBar.java:212-216) |
| 离散化 | stepSize>0 时 snapPosition 档位吸附(BaseSlider:2335-2342) | 原生 SeekBar 天然 int 取整 |
| 程序设值回调 | dispatchOnChangedProgrammatically,fromUser=false(BaseSlider:2642-2648) | 框架语义 |
| 触摸回调 | onValueChange(Slider, float, fromUser=true) | OnSeekBarChangeListener(框架) |
| 程序设值校验 | setValue 不校验,非法值在下次 onDraw 抛 ISE(BaseSlider:741-752) | 框架 clamp |
6. 本仓库内的死/旧代码(排障时别被骗)
ABW/SeekBar.java:@Deprecated、全仓零引用,纯历史遗留。BaseSlider.mSeekBarLocation(:326):声明后从未使用(死字段);同名活字段在 micarxAppCompatSeekBar(:34,参与 computeTouchOffset)。grep 时勿混淆。BaseSlider.mPressThumbEnlargeEnable(:346):读出后无消费方,用途未确认。SliderThemeDelegate.adjustActiveTrackEndPixel:BaseSlider 内无调用,唯一消费方是PlayerProgressbar.java:112。