本文主要是介绍getWidth与getMeasureWidth,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
getWidth
以ImageView为例,源代码:
public final int getWidth() {return mRight - mLeft;}
可以发现该方法是final的,只有在View类中有。而在View类中mRight与mLeft的赋值只有在protected boolean setFrame(int left, int top, int right, int bottom)方法中进行。同时在ImageView中没有发现有方法会对mRight进行赋值。
而setFrame()的方法片断如下:
mLeft = left;mTop = top;mRight = right;mBottom = bottom;
而在View中又只有layout()方法调用了setFrame()
public void layout(int l, int t, int r, int b) {int oldL = mLeft;int oldT = mTop;int oldB = mBottom;int oldR = mRight;boolean changed = setFrame(l, t, r, b);
因此,可以认为getWidth得到的只是layout()方法参数中的差值。
再看layout的参数说明:
left Left position, relative to parent
top Top position, relative to parent
right Right position, relative to parent
bottom Bottom position, relative to parent
四个参数分别指的是当前View在它的父View中的位置,并且是相对于它的父View来说的(也就是以父View的左上角为原点,向右为正,向下为正建立坐标系时,当前View的左上角(l,t)、右下角(r,b)分别的坐标),并不是相对于整个屏幕来说的。
下面以LinearLayout的onLayout()源代码为例,佐证上面四个参数的含义:
在LinearLayout的onLayout()发现它最终会调用layoutVertical(),layoutVertical()片断如下:
setChildFrame(child, childLeft, childTop + getLocationOffset(child),childWidth, childHeight);
而setChildFrame的代码为:
private void setChildFrame(View child, int left, int top, int width, int height) { child.layout(left, top, left + width, top + height);}
而在layoutVertical()方法中可以发现childTop是不断进行累加的,并且是在layoutVertical()中进行声明的。
因此,当调用到child.layout()时,传入的参数便是指:child在其父组件中的位置。并且是相对于它的父组件来说的。
由此可知:getWidth得到的是当前View在其父组件中的所占区域的宽度,也就是它的真实宽度(当调用完layout之后,该组件在父组件中所占的区域已经固定了,所以说是它的真实位置),并不是屏幕展示出来的宽度。
如:自定义一个类MyViewGroup继承于ViewGroup,重写其中的onLayout()方法,更改其子View所占的位置
@Overrideprotected void onLayout(boolean changed, int left, int top, int right,int bottom) {System.out.println(left+"/"+right+"/"+top+"/"+bottom+"/"+getWidth());for(int x = 0;x<getChildCount();x++){View view = getChildAt(x);view.layout(10, 0, getWidth()+123, getHeight()+200);}}
布局为:
<com.example.demo.MyViewGroupandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_marginLeft="20px"android:background="#ffffff"android:layout_weight="1"><ImageViewandroid:id="@+id/iv_after"android:layout_width="match_parent"android:layout_height="wrap_content"android:src="@drawable/big" /></com.example.demo.MyViewGroup>
其中,marginLeft的单位用的是px,而不是常用的dp,这是因为代码中得到的值都是px,dp与px是需要进行换算的,为了方便就不采用dp了。再在activity中调用imageView组件的getWidth()方法,得到的值是:573。
而onLayout()方法输入的结果是:20/480/0/378/460。
分析:
首先left的20是因为在布局文件中设置了margin_Left为20px。480是因为MyViewGroup是match_parent的(手机的宽也是480)。
其中ImageView.getWidth得到的是573:这是因为imageView在MyViewGroup中占的区域为(10,top)与(getWidth()(此处的getWidth指的是MyViewGroup的宽度,即460)+123,bottom)形成的矩形,该矩形的宽度便是460+123-10=573。
最后:由上面的分析知:
在layout方法结束之后,都可以调用组件的getWidth并且得到正确的值。如重写MyViewGroup的onDraw,在其中调用getWidth就可以得到正确的值。
getRight等方法返回的都该组件距其父组件边界的某些距离,并不是距离屏幕的。
getWidth():得到的是父View分配给子View的大小,即layout()中所指定的矩形的大小.这个值并不是子View的实际大小。如子View需要200px,但父View只能分配给它100px,此时getWidth就是100px。
getMeasureWidth():
得到的是该View自己的测量大小,准确点说是通过setMeasuredDimension()方法设置的大小。在measure阶段之后就可以调用该方法得到值了。因此,与getWidth并不是一回事。
这篇关于getWidth与getMeasureWidth的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!