获取Android控件的宽和高

转载+验证:本人已经验证过,请放心复制粘贴,嘿嘿~~~~~~省了你的时间了 

我们都知道在onCreate()里面获取控件的高度是0,这是为什么呢?我们来看一下示例:
首先我们自己写一个控件,这个控件非常简单:

 

 
 
  1. public class MyImageView extends ImageView {  
  2.   
  3.     public MyImageView(Context context, AttributeSet attrs) {  
  4.         super(context, attrs);  
  5.     }  
  6.     public MyImageView(Context context) {  
  7.         super(context);  
  8.     }  
  9.       
  10.     @Override  
  11.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  12.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  13.         System.out.println("onMeasure 我被调用了"+System.currentTimeMillis());  
  14.     }  
  15.       
  16.     @Override  
  17.     protected void onDraw(Canvas canvas) {  
  18.         super.onDraw(canvas);  
  19.         System.out.println("onDraw 我被调用了"+System.currentTimeMillis());  
  20.     }  
  21.   
  22. }  

 

 
 
  1. 布局文件: 
  2. [java]  
  3. <com.test.MyImageView  
  4.     android:id="@+id/imageview"  
  5.     android:layout_width="wrap_content"  
  6.     android:layout_height="wrap_content"  
  7.     android:src="@drawable/test" />  
  8.  
  9. 测试的Activity的onCreate(): 
  10. [java]  
  11. @Override  
  12. public void onCreate(Bundle savedInstanceState) {  
  13.     super.onCreate(savedInstanceState);  
  14.     setContentView(R.layout.main);          
  15.     System.out.println("执行完毕.."+System.currentTimeMillis());  
  16. }  

 

说明等onCreate方法执行完了,我们定义的控件才会被度量(measure),所以我们在onCreate方法里面通过view.getHeight()获取控件的高度或者宽度肯定是0,因为它自己还没有被度量,也就是说他自己都不知道自己有多高,而你这时候去获取它的尺寸,肯定是不行的.

在Android中,有时需要对控件进行测量,得到的控件宽度和高度可以用来做一些计算。在需要自适应屏幕的情况下,这种计算就显得特别重要。另一方便,由于需求的原因,希望一进入界面后,就能得到控件的宽度和高度。

可惜的是,根据我的验证,利用网上转载的那些方法在OnCreate函数中获取到的仍然是0(希望搞技术的能自己验证过再转载),例如Measure方法之后调用getMeasuredWidth的值还是0。


原因是因为当OnCreate函数发生时,只是提供了数据初始化的机会,此时还没有正式绘制图形。而绘制图形在OnDraw中进行,此时计算又显得太晚。容易想到的办法是:希望能在程序刚刚测量好某个指定控件后,拿到它的宽度和高度立刻进行计算或数据初始化。这就需要有一个方法来监听到这个事件的发生,幸好Android提供了这样的机制,利用View类中的getViewTreeObserver方法,可以获取到指定View的观察者,在绘制控件前的一刹那进行回调,这样速度上又不耽误,得到的数据由是准确的,但此方法在之后可能会被反复调用,因此需要加入限制,普通需求下,只计算一次就够了,代码如下(此代码在OnCreate回调函数中验证通过,实时上,因为它是监听器,所以发生事件时已经和OnCreate无关了):

方法一:(它的回调方法会调用很多次,并且滑动TextView的时候任然会调用,所以不建议使用2.3.x和4.0.4验证通过

 

 
 
  1.  ViewTreeObserver vto=imageView222.getViewTreeObserver(); 
  2.  vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
  3.      
  4.     @Override 
  5.     public boolean onPreDraw() { 
  6.         int height = imageView222.getHeight();  
  7.         int width = imageView222.getWidth();  
  8.         int meansureH=imageView222.getMeasuredHeight(); 
  9.         int meansureW=imageView222.getMeasuredWidth(); 
  10.         testView.append("\npre"+" height"+height+",width"+width);  
  11.         testView.append("\npre"+"\n measureH"+meansureH+",measureW"+meansureW);  
  12.         return true;  //这里返还为falsejian
  13.          
  14.     } 
  15.      
  16. }); //虽然是转载,但已验证,可行,此处得到的measureHeight和height值相同

 

方法二:

仅触发一次,建议使用,个人认为是最好的方式,是否有其他弊端不明显,2.3.x和4.0.4验证通过

 
 
  1. ViewTreeObserver vto2 = imageView222.getViewTreeObserver(); 
  2.         vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
  3.             @Override 
  4.             public void onGlobalLayout() { 
  5.                 imageView222.getViewTreeObserver() 
  6.                         .removeGlobalOnLayoutListener(this); 
  7.                 testView.append("\n global" + " height" 
  8.                         + imageView222.getHeight() + ",width" 
  9.                         + imageView222.getWidth()); 
  10.                 testView.append("\n global" + "measureH" 
  11.                         + imageView222.getMeasuredHeight() + ",measureW" 
  12.                         + imageView222.getMeasuredWidth()); 
  13.             } 
  14.         }); 

 

方法三:不建议使用,使用getHeight和getWidth得到的值仍然是0;getMeasuredHeight得到的值与最终在其他方法中得到的height和width值不同,个人验证认为是无效的

 

 
 
  1. int w = View.MeasureSpec.makeMeasureSpec(0, 
  2.                 View.MeasureSpec.UNSPECIFIED); 
  3.         int h = View.MeasureSpec.makeMeasureSpec(0, 
  4.                 View.MeasureSpec.UNSPECIFIED); 
  5.         imageView222.measure(w, h); 
  6.         int mHeight = imageView222.getMeasuredHeight(); 
  7.         int height = imageView222.getHeight(); 
  8.         int mWidth = imageView222.getMeasuredWidth(); 
  9.         int width = imageView222.getWidth(); 
  10.         testView.append("\n measere  Height" + height + ",width" + width); 
  11.         testView.append("\n measere MeasuredHeight" + mHeight 
  12.                 + ",MeasuredHeight" + mWidth); 

 

以下是验证截图:

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值