一、Android View体系概述
Android UI的核心是由View和ViewGroup构成的树形结构:
1、核心组件关系图2、关键角色View:基础绘制单元(TextView/ImageView等),处理测量、绘制、事件ViewGroup:容器(LinearLayout,FrameLayout等),负责子View的测量与布局Window -> DecorView --> ContentView树形结构
二、View工作流程核心机制1、Measure测量阶段代码语言:txt复制// 自定义View测量示例
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val minWidth = 100.dpToPx() // 最小宽度
val width = when (MeasureSpec.getMode(widthMeasureSpec)) {
MeasureSpec.EXACTLY -> MeasureSpec.getSize(widthMeasureSpec)
MeasureSpec.AT_MOST -> minOf(minWidth, MeasureSpec.getSize(widthMeasureSpec))
else -> minWidth // UNSPECIFIED
}
setMeasuredDimension(width, resolveHeight(heightMeasureSpec))
}
MesureSpec的三种模式EXACTLY:match_parent/固定尺寸,子View必须使用给定尺寸
AT_MOST:wrap_content,子View不能超过指定尺寸
UNSPECIFIED:ScrollView测量子View等场景,无限制
2. Layout布局阶段确定视图在布局中所在的位置
代码语言:txt复制// 自定义ViewGroup布局实现
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
var topPos = paddingTop
for (i in 0 until childCount) {
val child = getChildAt(i)
if (child.visibility != GONE) {
val childHeight = child.measuredHeight
child.layout(
paddingLeft,
topPos,
paddingLeft + child.measuredWidth,
topPos + childHeight
)
topPos += childHeight + spacing
}
}
}
3. Draw绘制阶段
绘制顺序源码解析:
代码语言:txt复制public void draw(Canvas canvas) {
// Step 1. 绘制背景
drawBackground(canvas);
// Step 2. 保存图层(可选)
if (!dirtyOpaque) onDraw(canvas);
// Step 3. 绘制子View
dispatchDraw(canvas);
// Step 4. 绘制装饰(滚动条等)
onDrawForeground(canvas);
}
三、事件分发机制事件传递的一个UML序列图:
核心方法:dispatchTouchEvent(MotionEvent ev), onInterceptTouchEvent(MotionEvent ev) (仅 ViewGroup), onTouchEvent(MotionEvent ev)。传递流程: Activity -> Window (PhoneWindow) -> DecorView (顶级ViewGroup) -> 子View... (树形结构自上而下)。责任链模式: ViewGroup 通过 onInterceptTouchEvent 决定是否拦截事件,不拦截则向下分发 (dispatchTouchEvent 到子 View);子 View 通过 onTouchEvent 决定是否消费事件,不消费则向上回传。触摸事件冲突: 常见类型(同方向滑动、嵌套滑动、点击与滑动),解决方法(外部拦截法 - 重写父容器 onInterceptTouchEvent;内部拦截法 - 子 View 配合 requestDisallowInterceptTouchEvent)。NestedScrolling 机制:。