CaptionWindowDecoration 显示方式分析

1. 整体架构

CaptionWindowDecoration 采用了多层Surface架构来显示窗口装饰:

1
2
3
4
5
Task Surface (任务表面)
├── Decoration Container Surface (装饰容器表面)
└── Caption Container Surface (标题栏容器表面)
└── View Host (视图宿主)
└── Caption View (标题栏视图)

2. 显示机制详解

A. Surface层次结构

1
2
3
4
5
6
7
8
9
10
11
12
13
// 第1层:Decoration Container Surface
mDecorationContainerSurface = builder
.setName("Decor container of Task=" + mTaskInfo.taskId)
.setContainerLayer()
.setParent(mTaskSurface) // 父级是Task Surface
.build();

// 第2层:Caption Container Surface
mCaptionContainerSurface = builder
.setName("Caption container of Task=" + mTaskInfo.taskId)
.setContainerLayer()
.setParent(mDecorationContainerSurface) // 父级是Decoration Container
.build();

B. 视图渲染机制

1
2
3
// 使用SurfaceControlViewHost连接Surface和View
mViewHost = new SurfaceControlViewHost(mDecorWindowContext, mDisplay, mCaptionWindowManager);
mViewHost.setView(outResult.mRootView, lp); // 设置标题栏视图

3. 布局文件结构

caption_window_decor.xml 可以看到:

1
2
3
4
5
6
7
<WindowDecorLinearLayout android:id="@+id/caption">
<Button android:id="@+id/back_button" /> <!-- 返回按钮 -->
<Space android:layout_weight="1" /> <!-- 弹性空间 -->
<Button android:id="@+id/minimize_window" /> <!-- 最小化按钮 -->
<Button android:id="@+id/maximize_window" /> <!-- 最大化按钮 -->
<Button android:id="@+id/close_window" /> <!-- 关闭按钮 -->
</WindowDecorLinearLayout>

4. 显示流程

步骤1:创建Surface层次

1
2
3
// 在updateViewsAndSurfaces()中
updateDecorationContainerSurface(startT, outResult); // 创建装饰容器
updateCaptionContainerSurface(startT, outResult); // 创建标题栏容器

步骤2:布局计算

1
2
3
4
5
// 计算标题栏位置和大小
outResult.mCaptionHeight = loadDimensionPixelSize(resources, params.mCaptionHeightId);
outResult.mCaptionWidth = loadDimensionPixelSize(resources, params.mCaptionWidthId);
outResult.mCaptionX = calculateCaptionX(outResult.mWidth, outResult.mCaptionWidth);
outResult.mCaptionY = calculateCaptionY(outResult.mHeight, outResult.mCaptionHeight);

步骤3:视图绑定

1
2
// 在updateViewHost()中
mViewHost.setView(outResult.mRootView, lp); // 将布局绑定到Surface

5. 关键特性

A. 无窗口显示

1
2
3
4
5
6
// 使用WindowlessWindowManager实现无窗口显示
mCaptionWindowManager = new WindowlessWindowManager(
mTaskInfo.getConfiguration(),
mCaptionContainerSurface,
null /* hostInputToken */
);

B. 输入事件处理

1
2
3
4
5
6
// 设置触摸监听器
caption.setOnTouchListener(mOnCaptionTouchListener);
close.setOnClickListener(mOnCaptionButtonClickListener);
back.setOnClickListener(mOnCaptionButtonClickListener);
minimize.setOnClickListener(mOnCaptionButtonClickListener);
maximize.setOnClickListener(mOnCaptionButtonClickListener);

C. 动态颜色调整

1
2
3
4
// 根据背景色自动调整按钮颜色
final int buttonTintColorRes = Color.valueOf(captionColor).luminance() < 0.5
? R.color.decor_button_light_color
: R.color.decor_button_dark_color;

6. 显示优势

  1. 性能优化:使用Surface直接渲染,避免View层级开销
  2. 输入处理:支持拖拽、点击等复杂交互
  3. 动态更新:可以实时调整位置、大小、颜色
  4. 层级控制:通过Z-order精确控制显示层级
  5. 内存效率:Surface复用,减少内存占用

7. 总结

CaptionWindowDecoration 采用了现代Android图形架构

  • Surface + View混合渲染:结合了Surface的高性能和View的灵活性
  • 分层显示架构:通过多层Surface实现复杂的窗口装饰效果
  • 无窗口管理:使用WindowlessWindowManager实现轻量级显示
  • 动态布局系统:支持实时调整位置、大小和样式

这种设计使得窗口装饰既保持了高性能,又具备了丰富的交互能力和视觉效果。