题外话:刚开始接触工作的时候,就是依靠百度工作,渐渐的发现,其实最好的导师其实是我们的官网API文档,最好的搜索引擎必然是科学上网!
对于某个知识点,模糊模棱两可的时候,想要弄明白,除啦自己实践,无其他捷径,
自定义view 大家都肯定会写,面试的那个套路基本也能应付几句,今天没事,看下view中的测量模式,想想我们以前写的自定义view 是不是像谷歌给我们提供的Textview一样好用,可以match 可以 wrap 可以 写死,支持padding 等,
一个标准的自定义view应该是参考textview那样,这样一来完善自己的自定义view必然要涉及到测量模式!
测量模式有三种引用官方的解释如下
UNSPECIFIED
The parent has not imposed any constraint on the child. It can be whatever size it wants.
父View没有对自定义View的大小做任何限制,自定义View想多大就多大,但是不能超过父View的大小
EXACTLY
The parent has determined an exact size for the child. The child is going to be given those bounds regardless of how big it wants to be.
父View给自定义View确定了一个范围,在这个范围内,自定义view的大小是给出的具体的值,比如 width =100dp,height=200dp,但是如果给出的任何一个数值超过了父View的限制值,他最大是父View的限制值
AT_MOST
The child can be as large as it wants up to the specified size.
父View没有对自定义控件做任何限制,想多大就多大,可以超过父View的大小,
单独看概念,可能需要理解一下,我们自己动手写一个测试的View,看下结果就明白了,
我们的就写一个MeasurView 继承View然后在onMesusre中什么都不干,就打印下当前的不同模式,测量出来的宽和高,
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width = 0;
int height = 0;
Log.e(TAG, "onMeasure: >>>测量模式-->" + okText + "--->>" + widthMode + "-->>heightMode-->" + heightMode + "--->>wSize-->>" + widthSize + "--->>hSize-->>" + heightSize);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
width = widthSize;
} else if (widthMode == MeasureSpec.UNSPECIFIED) {
width = widthSize;
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
height = heightSize;
} else if (heightMode == MeasureSpec.UNSPECIFIED) {
height = heightSize;
}
在不处理onMeasu的情况,wrapcent 和 matchparent 是一样的效果,
全部是撑满父View
既然都是沾满父View,那AT_MOST 和 UNSPECIFIED还有啥区别,
这个区别我们可以改变下onMesuer的代码即可看出,
我们把UNSPECIFIED 和AT_MOST的情况下的宽和高全部都用代码设置成2000dp,这个值大部分的手机屏幕都是达不到的,电视除外,
这样就能看出区别了,
结果根据官网给的文档也能猜出来,只有AT_MOST模式下,我们能看到2000DP的效果,其他两种模式全部父View的大小,被父View限制了,只有AT_MOST是无法无天的,
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width = 0;
int height = 0;
Log.e(TAG, "onMeasure: >>>测量模式-->" + okText + "--->>" + widthMode + "-->>heightMode-->" + heightMode + "--->>wSize-->>" + widthSize + "--->>hSize-->>" + heightSize);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
width = 2000;
} else if (widthMode == MeasureSpec.UNSPECIFIED) {
width = 2000;
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
height = 2000;
} else if (heightMode == MeasureSpec.UNSPECIFIED) {
height = 2000;
}
注意我现在焦点是放在第二个view上的,我们在xml中第二个的宽高属性全部是wrap_content,然后我们用代码给他设置成2000dp,灰色的部分都超过了手机屏幕,也就是父view没有对他做出限制,
其他两个view的宽高属性,第一个是 EXACTLY 写死的2000dp;
但是由于宽和高都超过了父View的大小,所以父view给限制了,
第三个是matchparent 然后代码改变为2000dp,也被父View被限制了
通过上面的简单测试,可以加深自己对测量模式的,理解,这只是表面的,想看具体原理的去啃源码,毕竟哥们也是Android小屌丝一个,深度还没达到…….
结束!!!