目录
1. 整体架构
1.1 三层架构图
Controller层 View层 Window层 控制 控制 协调 协调 控制 控制 TaskbarViewController StashedHandleViewController TaskbarStashController NavbarButtonsViewController TaskbarDragLayerController TaskbarDragLayer
顶层容器 TaskbarView
主要内容区 StashedHandleView
收起时的Handle TaskbarScrimView
背景遮罩 导航按钮区域 Window Manager
TYPE_NAVIGATION_BAR_PANEL
1.2 屏幕显示效果(Unstashed状态)
┌─────────────────────────────────────────────┐
│ │
│ 应用内容区域 │
│ │
│ │
│ │
├─────────────────────────────────────────────┤ ← 应用与Taskbar分界线
│ 🔍 📱 📧 🌐 📷 🎵 ⚙️ [≡] │ ← TaskbarView (80dp高)
│ ⬆️ 🏠 ◼️ │ ← 导航按钮
└─────────────────────────────────────────────┘
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
QSB 应用图标(Hotseat) AllApps按钮
1.3 屏幕显示效果(Stashed状态)
┌─────────────────────────────────────────────┐
│ │
│ 应用内容区域 │
│ (使用全屏) │
│ │
│ │
│ ⬆️ 🏠 ◼️ │ ← 导航按钮
├─────────────────────────────────────────────┤
│ ━━━━━━━━━━━ │ ← StashedHandleView (24dp高)
└─────────────────────────────────────────────┘
↑
Handle (可点击唤起)
2. View层级结构
2.1 完整View树
FrameLayout
全屏容器] Root --> TaskbarView[TaskbarView
FrameLayout
图标容器] Root --> StashedHandle[StashedHandleView
ImageView
收起Handle] Root --> TaskbarScrim[TaskbarScrimView
View
背景遮罩] Root --> NavFrame[FrameLayout
导航按钮容器] TaskbarView --> Icons[App Icons
BubbleTextView × N
应用图标] TaskbarView --> AllApps[AllAppsButton
ImageView
所有应用按钮] TaskbarView --> QSB[QSB Container
FrameLayout
搜索栏] TaskbarView --> Folder[FolderIcon
文件夹图标] NavFrame --> Back[Back Button
返回] NavFrame --> Home[Home Button
主页] NavFrame --> Recent[Recent Button
最近任务] style Root fill:#E1F5FE style TaskbarView fill:#C8E6C9 style StashedHandle fill:#FFCCBC style Icons fill:#FFF9C4 style NavFrame fill:#F8BBD0
2.2 View层级代码表示
java
TaskbarDragLayer (R.id.taskbar_drag_layer) // 1920×80dp (全屏宽度)
├── TaskbarView (R.id.taskbar_view) // MATCH_PARENT × 80dp
│ ├── QSB Container // 搜索栏 (可选)
│ ├── BubbleTextView (icon 1) // 应用图标1 (48dp)
│ ├── BubbleTextView (icon 2) // 应用图标2 (48dp)
│ ├── BubbleTextView (icon 3) // 应用图标3 (48dp)
│ ├── BubbleTextView (icon 4) // 应用图标4 (48dp)
│ ├── BubbleTextView (icon 5) // 应用图标5 (48dp)
│ ├── FolderIcon (可选) // 文件夹图标
│ └── AllAppsButton // 所有应用按钮 (48dp)
│
├── StashedHandleView // Handle条 (120×4dp)
│
├── TaskbarScrimView // 背景遮罩层
│
└── FrameLayout (导航按钮容器) // 右侧导航区
├── ImageButton (Back) // 返回按钮
├── ImageButton (Home) // Home按钮
└── ImageButton (Recent) // 最近任务按钮
3. TaskbarView详细组成
3.1 TaskbarView布局示意图
┌──────────────────────────────────────────────────────────────────────┐
│ TaskbarView (高度80dp, 宽度MATCH_PARENT) │
├──────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌────┐ │
│ │ 🔍 │ │📱│ │📧│ │🌐│ │📷│ │🎵│ │⚙️│ │📁│ │ ≡ │ │
│ │QSB │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │All │ │
│ └────┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └────┘ │
│ │
│ ← 4dp→←8→←48dp→←8→←48→←8→←48→←8→←48→←8→←48→←8→←48→←8→←48→←8→ │
│ │
└──────────────────────────────────────────────────────────────────────┘
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
边距 间距 图标 间距 图标 ... AllApps
3.2 图标类型说明
a) BubbleTextView(应用图标)
┌────────────┐
│ │ ← 48dp × 48dp 触摸区域
│ 📱 │ ← 图标 (实际36-40dp)
│ │
│ App │ ← 应用名称 (可选显示)
└────────────┘
属性:
- mIconTouchSize: 48dp (触摸区域)
- actualIconSize: 36-40dp (图标大小)
- mItemMarginLeftRight: 8dp (左右间距)
- mItemPadding: 4dp (内边距)
b) FolderIcon(文件夹图标)
┌────────────┐
│ 📱 📧 │ ← 48dp × 48dp
│ 🌐 📷 │ ← 4个预览图标
│ │
│ Folder │ ← 文件夹名称
└────────────┘
特点:
- 最多显示4个预览图标
- 点击展开Folder内容
- 支持拖拽添加/移除应用
c) AllAppsButton(所有应用按钮)
┌────────────┐
│ │ ← 48dp × 48dp
│ ≡ │ ← 三条横线图标
│ │
└────────────┘
功能:
- 点击打开All Apps抽屉
- Feature Flag控制显示
- PC模式下隐藏
d) QSB(搜索栏)
┌──────────────────────┐
│ 🔍 Search apps... │ ← 高度: 48-56dp
└──────────────────────┘
位置:
- RTL布局: 最右侧
- LTR布局: 最左侧
- 可选显示 (Feature Flag)
3.3 图标布局计算逻辑
java
// TaskbarView.java
public class TaskbarView extends FrameLayout {
// 计算图标位置
private void layoutIcons() {
int actualIconSize = mActivityContext.getDeviceProfile().iconSizePx; // 36-40dp
int actualMargin = getResources().getDimensionPixelSize(
R.dimen.taskbar_icon_spacing); // 8dp
// 触摸区域大小(保证最小48dp)
mIconTouchSize = Math.max(actualIconSize,
getResources().getDimensionPixelSize(
R.dimen.taskbar_icon_min_touch_size)); // 48dp
// 实际间距调整
mItemMarginLeftRight = actualMargin - (mIconTouchSize - actualIconSize) / 2;
mItemPadding = (mIconTouchSize - actualIconSize) / 2;
// 布局参数
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
mIconTouchSize,
mIconTouchSize
);
lp.leftMargin = mItemMarginLeftRight;
lp.rightMargin = mItemMarginLeftRight;
}
}
3.4 动画属性
TaskbarView的图标支持以下动画属性:
| 属性 | 取值范围 | 动画时长 | 用途 |
|---|---|---|---|
| Alpha | 0.0 ~ 1.0 | 300ms | Stash时淡入淡出 |
| ScaleX/Y | 0.5 ~ 1.0 | 300ms | Stash时缩放 |
| TranslationY | -80dp ~ 0 | 300ms | Stash时下移 |
| Rotation | 0° ~ 360° | 200ms | 文件夹打开动画 |
| Background Color | 透明 ~ 半透明 | 200ms | 主题图标背景 |
4. Controller层级
4.1 Controller架构图
Logic Controllers View Controllers 核心Controllers 协调 协调 TaskbarStashController
协调显示隐藏 TaskbarDragController
处理拖拽 TaskbarLauncherStateController
同步Launcher状态 TaskbarRecentAppsController
最近任务 TaskbarAllAppsController
所有应用 TaskbarViewController
控制图标显示 StashedHandleViewController
控制Handle TaskbarDragLayerController
控制顶层容器 TaskbarScrimViewController
控制背景遮罩 NavbarButtonsViewController
控制导航按钮 TaskbarActivityContext
主上下文 TaskbarControllers
控制器容器
4.2 Controller职责表
| Controller | 主要职责 | 控制的View | 关键方法 |
|---|---|---|---|
| TaskbarViewController | 管理应用图标 | TaskbarView | init(), updateIconAlpha(), updateIconScale() |
| StashedHandleViewController | 管理Handle | StashedHandleView | init(), updateScale(), onStashedHandleClick() |
| TaskbarStashController | 协调Stash逻辑 | 无(协调器) | updateStateForFlag(), applyState(), createAnimToIsStashed() |
| TaskbarDragLayerController | 管理顶层容器 | TaskbarDragLayer | init(), setTouchableRegion() |
| NavbarButtonsViewController | 管理导航按钮 | 导航按钮容器 | init(), updateNavButtonColor() |
| TaskbarDragController | 处理拖拽事件 | 无 | onDragStart(), onDrop() |
| TaskbarScrimViewController | 管理背景遮罩 | TaskbarScrimView | updateScrimAlpha() |
| TaskbarAllAppsController | 管理All Apps | AllAppsButton | toggle(), show(), hide() |
| TaskbarRecentAppsController | 管理最近任务 | 无 | loadRecentApps() |
4.3 Controller交互流程
User TaskbarStashController TaskbarViewController StashedHandleViewController TaskbarView/HandleView 触发Stash (如打开应用) updateStateForFlag(FLAG_IN_APP, true) applyState(300ms) computeIsStashed() → true 创建图标动画 Alpha 1→0 Scale 1→0.5 TransY 0→-80 创建Handle动画 Alpha 0→1 Scale 1→1 更新TaskbarView属性 图标淡出缩小下移 更新HandleView属性 Handle淡入显示 par [并行执行动画] 300ms后动画完成 只显示Handle User TaskbarStashController TaskbarViewController StashedHandleViewController TaskbarView/HandleView
5. 交互流程
5.1 用户交互场景
系统启动 打开应用/手动收起 点击Handle/返回桌面 点击图标 启动应用 应用前台 长按图标 显示菜单 关闭菜单 拖拽图标 放下图标 完成拖拽 点击Handle 展开Taskbar Unstashed Stashed IconClick AppLaunched IconLongPress ShowMenu DragIcon DropIcon HandleClick 显示完整Taskbar
- 应用图标
- All Apps按钮
- 导航按钮 只显示Handle
- 应用图标隐藏
- Handle显示
- 导航按钮保持
5.2 触摸事件分发
Taskbar区域 Handle区域 导航按钮区域 其他区域 是 长按 拖拽 Back Home Recent 用户触摸屏幕 TaskbarDragLayer
onTouchEvent 触摸区域判断 TaskbarView
onTouchEvent StashedHandleView
onTouchEvent NavButtons
onTouchEvent 事件透传 点击图标? 启动应用 显示弹窗菜单 开始拖拽 展开Taskbar 按钮类型 返回 回桌面 最近任务 应用接收事件
5.3 Stash/Unstash触发条件
6. 尺寸与布局
6.1 标准尺寸定义
java
// 尺寸资源 (res/values/dimens.xml)
<dimen name="taskbar_size">80dp</dimen> // Taskbar整体高度
<dimen name="taskbar_stashed_size">24dp</dimen> // Stashed状态高度
<dimen name="taskbar_icon_min_touch_size">48dp</dimen> // 图标最小触摸区域
<dimen name="taskbar_icon_spacing">8dp</dimen> // 图标间距
<dimen name="taskbar_stashed_handle_width">120dp</dimen> // Handle宽度
<dimen name="taskbar_stashed_handle_height">4dp</dimen> // Handle高度
<dimen name="taskbar_nav_buttons_width">192dp</dimen> // 导航按钮区域宽度
<dimen name="taskbar_nav_buttons_size">44dp</dimen> // 单个导航按钮大小
6.2 布局尺寸示意图(精确尺寸)
屏幕宽度: 1920px (假设密度3.0, 即640dp)
┌────────────────────────────────────────────────────────────────┐
│ 屏幕顶部 │
│ ... │
│ │
├────────────────────────────────────────────────────────────────┤
│ TaskbarDragLayer (640dp × 80dp) │
├────────────────────────────────────────────────────────────────┤
│ │
│ ┌────┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌────┐ ┌──┬──┬──┐ │
│ │ 🔍 │ │📱│ │📧│ │🌐│ │📷│ │🎵│ │ ≡ │ │⬆️│🏠│◼️│ │
│ │56dp│ │48│ │48│ │48│ │48│ │48│ │48dp│ │44│44│44│ │
│ └────┘ └──┘ └──┘ └──┘ └──┘ └──┘ └────┘ └──┴──┴──┘ │
│ │
│ ← 4→←8→←48→←8→←48→←8→←48→←8→←48→←8→←48→←8→←48→ ← 16 → │
│ │
│ ← TaskbarView (约400dp) → ← 空白 → ← NavButtons → │
│ (192dp) │
└────────────────────────────────────────────────────────────────┘
↑ ↑
屏幕左边缘 屏幕右边缘
6.3 Stashed状态尺寸
┌────────────────────────────────────────────────────────────────┐
│ TaskbarDragLayer (640dp × 24dp) │
├────────────────────────────────────────────────────────────────┤
│ │
│ ━━━━━━━━━━━ ┌──┬──┬──┐ │
│ Handle │⬆️│🏠│◼️│ │
│ (120×4dp) └──┴──┴──┘ │
│ │
│ ← 居中对齐 → ← NavButtons (192dp) → │
└────────────────────────────────────────────────────────────────┘
6.4 不同屏幕密度适配
| 密度 | 倍率 | Taskbar高度 | 图标大小 | Handle高度 |
|---|---|---|---|---|
| mdpi | 1.0x | 80px | 48px | 24px |
| hdpi | 1.5x | 120px | 72px | 36px |
| xhdpi | 2.0x | 160px | 96px | 48px |
| xxhdpi | 3.0x | 240px | 144px | 72px |
| xxxhdpi | 4.0x | 320px | 192px | 96px |
6.5 横竖屏布局差异
横屏(Landscape)
┌──────────────────────────────────────────────────────────────────────┐
│ 应用内容 │
│ │
└──────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
│ 🔍 📱 📧 🌐 📷 🎵 ⚙️ 📁 [≡] ⬆️ 🏠 ◼️ │
└──────────────────────────────────────────────────────────────────────┘
↑ Taskbar固定在底部
竖屏(Portrait)- 部分设备支持
┌─────────────────┐
│ │
│ 应用内容 │
│ │
│ │
│ │
│ │
│ │
│ │
├─────────────────┤
│ 🔍 │
│ 📱 │
│ 📧 │ ← Taskbar可能在侧边
│ 🌐 │
│ 📷 │
│ ⚙️ │
│ │
│ ⬆️ 🏠 ◼️ │
└─────────────────┘
7. 视觉样式
7.1 颜色主题
java
// 默认颜色
public static final float TASKBAR_BACKGROUND_LUMINANCE = 0.30f;
// 浅色主题
背景色: #E8E8E8 (浅灰)
图标色: #000000 (黑色)
Handle色: #DADCE0 (灰色)
// 深色主题
背景色: #1F1F1F (深灰)
图标色: #FFFFFF (白色)
Handle色: #5F6368 (深灰)
// 动态主题(Material You)
背景色: 主题色 @ 30% luminance
图标色: 动态适配
Handle色: 主题色 @ 50% opacity
7.2 阴影与圆角
java
// TaskbarView
elevation: 16dp // 阴影高度
corner_radius: 24dp // 圆角半径(顶部)
background_alpha: 0.7 // 背景透明度
// StashedHandleView
elevation: 0dp // 无阴影
corner_radius: 2dp // 小圆角
background_alpha: 0.5 // 半透明
7.3 动画曲线
java
// Interpolators
EMPHASIZED: 先慢后快再慢 (Material Design标准)
LINEAR: 线性
DECELERATE: 减速
ACCELERATE: 加速
// 使用场景
Stash动画: EMPHASIZED (300ms)
图标点击: DECELERATE (150ms)
Handle提示: LINEAR (500ms)
8. 完整交互流程图
点击图标 长按图标 拖拽图标 点击Handle 点击AllApps 点击导航 是 否 卸载 应用信息 取消 Taskbar 删除区 文件夹 Back Home Recent 用户操作 操作类型 TaskbarView.onClickIcon TaskbarView.onLongClickIcon TaskbarDragController.onDragStart StashedHandleView.onClick AllAppsButton.onClick NavButton.onClick 启动应用 切换到应用 应该Stash? 执行Stash动画 保持Unstashed 显示弹出菜单 菜单操作 卸载应用 打开应用信息 关闭菜单 进入拖拽状态 拖动图标 放下位置 重新排序 移除图标 添加到文件夹 执行Unstash动画 显示完整Taskbar 打开All Apps抽屉 按钮类型 返回 回到桌面 显示最近任务 完成
9. 关键代码位置索引
| 组件 | 源文件 | 关键方法 |
|---|---|---|
| TaskbarView | TaskbarView.java | init(), updateHotseatItems(), getIconViews() |
| StashedHandleView | StashedHandleView.java | init(), setTranslationY(), setAlpha() |
| TaskbarDragLayer | TaskbarDragLayer.java | recreateControllers(), onDestroy() |
| TaskbarViewController | TaskbarViewController.java | init(), updateScale(), updateTranslationY() |
| StashedHandleViewController | StashedHandleViewController.java | init(), updateScale(), onStashedHandleClick() |
| TaskbarStashController | TaskbarStashController.java | updateStateForFlag(), applyState(), createAnimToIsStashed() |
| TaskbarControllers | TaskbarControllers.java | init(), 包含所有Controller引用 |
| TaskbarActivityContext | TaskbarActivityContext.java | initWindow(), updateDeviceProfile() |
10. 总结
核心组件
-
View层:
- TaskbarDragLayer(容器)
- TaskbarView(图标)
- StashedHandleView(Handle)
-
Controller层:
- TaskbarViewController(图标控制)
- StashedHandleViewController(Handle控制)
- TaskbarStashController(状态协调)
-
关键尺寸:
- 整体高度: 80dp
- Stashed高度: 24dp
- 图标大小: 48dp
UI特点
- 🎨 支持Material You动态主题
- 🌓 支持浅色/深色模式
- 📱 响应式布局适配不同屏幕
- ✨ 流畅的Stash/Unstash动画
- 👆 优化的触摸交互体验