来源参考Hencoder
2-1 Hencoder自定义 View 第二部分——布局过程的自定义
布局过程的工作内容
两个阶段:测量阶段和布局阶段。
测量阶段:从上到下递归地调用每个 View 或者 ViewGroup 的 measure() 方法,测量他们的尺寸并计算它们的位置;
布局阶段:从上到下递归地调用每个 View 或者 ViewGroup 的 layout() 方法,把测得的它们的尺寸和位置赋值给它们。
主要的思想:从父类一直传递到子类,来操作view的尺寸位置。具体见视频。
重写 onMeasure() 来修改已有的 View 的尺寸,也就是重写 onMeasure() 来修改已有的 View 的尺寸的具体做法:
- 重写 onMeasure() 方法,并在里面调用 super.onMeasure(),触发原有的自我测量;
- 在 super.onMeasure() 的下面用 getMeasuredWidth() 和 getMeasuredHeight() 来获取到之前的测量结果,并使用自己的算法,根据测量结果计算出新的结果;
- 调用 setMeasuredDimension() 来保存新的结果。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int measuredWidth = getMeasuredWidth();//通过这个获取原先的宽度
int measuredHeight = getMeasuredHeight();//通过这个获取原先的高度
//通过某些运算,计算出需要的新尺寸
if (measuredWidth > measuredHeight) {
measuredWidth = measuredHeight;
} else {
measuredHeight = measuredWidth;
}
setMeasuredDimension(measuredWidth, measuredHeight);
}
补充一个他视频里的viewgroup绘制和布局过程的截图:
(view的布局,layout为空,不需要调用子类)
2-2 目前在公众号。。
主要就是讲:全新定义自定义 View 尺寸的方式
- 重新 onMeasure(),并计算出 View 的尺寸;
- 使用 resolveSize() 来让子 View 的计算结果符合父 View 的限制(当然,如果你想用自己的方式来满足父 View 的限制也行。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int measuredWidth = getMeasuredWidth();//通过这个获取宽度
int measuredHeight = getMeasuredHeight();//通过这个获取高度
if (measuredWidth > measuredHeight) {
measuredWidth = measuredHeight;
} else {
measuredHeight = measuredWidth;
}
/***重点在这里****/
//两行代码,搞定这个子类的长宽度,而且符合开发者的要求
//过滤一下尺寸大小,传入测量得来的尺寸(比如:measuredWidth )以及父类给的尺寸(比如:widthMeasureSpec)
final int finalWidth = resolveSize(measuredWidth,widthMeasureSpec);
final int finalHeight = resolveSize(measuredHeight ,heightMeasureSpec);
setMeasuredDimension(finalWidth , finalHeight );
}
resolveSize:内部还是getMode/size,然后经过处理得出修改后的尺寸。
感谢Hencoder,致敬。