ViewGroup 的自定义(继承 ViewGroup)
需要进行以下两步:
-
重写 onMeasure() 来计算内部布局;
将控件需要的空间通过 setMeasuredDimension(xxx, xxx) 保存。 -
重写 onLaytout 来摆放子 View;
此方法的参数代表着整个控件的摆放位置坐标。 至于 子View 摆在哪里, 如何摆,都是建立在摆放的位置坐标基础上的。
具体一点来说,就是:
重写 onMeasure()
分以下 3 步
1.计算传递给子view约束条件。也就是给 子View 的两个MeasureSpec.
- 计算方式有两种:
第一种:
- 结合开发者要求(通过child.getLayoutParams()获得Layout_XXX)和自己的可用空间(自己的尺寸上限 - 已用尺寸)
- 尺寸上限根据自己的 MeasureSpec 中的 Mode 而定;
- 如果是 AT_MOST/EXACTLY, 那么尺寸上限就是 MeasureSpec 中 size
- 如果是 UNSPECIFIED, 尺寸无上限
第二种:
for (int i = 0; i < getChildCount(); i++) {
View childView = getChildAt(i);
LayoutParams layoutParams = childView.getLayoutParams();
int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, 0, layoutParams
.width);
int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, 0, layoutParams
.height);
childView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
-
调用每个子 View 的 measure(), 传入上一步计算的 MeasureSpec。
-
在子 View 进行计算, 并在最后 setDimension 保存子 View 的位置和尺寸
-
计算自己的尺寸并用 setMeasuredDimension() 保存
重写 onLayout
父view 在遍历所有 子View 的 onMeasure(...) 之后就可以拿到每个 子View 需要占用的空间,然后 父View 就接着遍历所有 子View 的 onLayout(...), onLayout 的参数就是 父View 分配给 子View 摆放的位置。
网友评论