如何获取view的宽度和高度

ViewTreeObserver下有六个接口:

包含下面6个事件:

interface  ViewTreeObserver.OnDrawListener

挡在一个视图树绘制时,所要调用的回调函数的接口类(level 16)

interface          ViewTreeObserver.OnGlobalFocusChangeListener  
当在一个视图树中的焦点状态发生改变时,所要调用的回调函数的接口类

interface         ViewTreeObserver.OnGlobalLayoutListener
当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时,所要调用的回调函数的接口类

interface          ViewTreeObserver.OnPreDrawListener
当一个视图树将要绘制时,所要调用的回调函数的接口类

interface          ViewTreeObserver.OnScrollChangedListener
当一个视图树中的一些组件发生滚动时,所要调用的回调函数的接口类

interface         ViewTreeObserver.OnTouchModeChangeListener
当一个视图树的触摸模式发生改变时,所要调用的回调函数的接口类
----------------------------------------------------------------------------------
    oncreate()方法中获取控件的宽高,只会得到0,原因是oncreate()方法执行完成后控件才会被度量(measure),所以我们在onCreate方法里面通过view.getHeight()获取控件的高度或者宽度肯定是0,因为它自己还没有被度量,也就是说他自己都不知道自己有多高,而你这时候去获取它的尺寸,肯定是不行的.
解决方法:

//————————————————方法一
调用measure方法重新测量控件,从而获取宽度和高度
int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); 
int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED); 
imageView.measure(w, h); 
int height =imageView.getMeasuredHeight(); 
int width =imageView.getMeasuredWidth(); 
textView.append("\n"+height+","+width); 
//———————————————–方法二
在画控件之前获取宽度和高度
ViewTreeObserver vto = imageView.getViewTreeObserver(); 
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
    public boolean onPreDraw() { 
        int height = imageView.getMeasuredHeight(); 
        int width = imageView.getMeasuredWidth(); 
        textView.append("\n"+height+","+width); 
        return true; 
    } 
}); 
//———————————————–方法三
//控件的可视状态发生改变时,获取宽度和高度
ViewTreeObserver vto2 = imageView.getViewTreeObserver();   
vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    @Override   
    public void onGlobalLayout() { 
        imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);   
        textView.append("\n\n"+imageView.getHeight()+","+imageView.getWidth()); 
    }   
});   
方法一: 比其他的两个方法多了一次计算,也就是多调用了一次onMeasure()方法,该方法虽然看上去简单,但是如果要目标控件计算耗时比较大的话(如listView等),不建议使用.
方法二,在绘制前执行回调方法,它的回调方法会调用很多次,并且滑动TextView的时候任然会调用,所以不建议使用.
方法三,当layout或控件的visibility被调用时,执行此回调

方法四:
    private void measureItem(View child) { 
         ViewGroup.LayoutParams p = child.getLayoutParams(); 
         if (p == null) { 
             p = new ViewGroup.LayoutParams( 
                     ViewGroup.LayoutParams.MATCH_PARENT, 
                     ViewGroup.LayoutParams.WRAP_CONTENT); 
         } 

         int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, 
                 mListPadding.left + mListPadding.right, p.width); 
         int lpHeight = p.height; 
         int childHeightSpec; 
         if (lpHeight > 0) { 
             childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); 
         } else { 
             childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 
         } 
         child.measure(childWidthSpec, childHeightSpec); 
     } 

猜你喜欢

转载自1029457926.iteye.com/blog/2187929