获取控件的宽和高

一:自定义MyImageView继承ImageView

/**
 * 这个类纯粹是为了看到控件的onMeasure方法和onDraw方法的执行情况
 * 任何控件都是同一个道理
 * @author Administrator
 *
 */
public class MyImageView extends ImageView {

	public MyImageView(Context context) {
		super(context);
	}
	public MyImageView(Context context, AttributeSet attrs) {  
        super(context, attrs);  
    } 
	/**
	 * 测量当前控件获取精确的宽和高
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		System.out.println("onMeasure 我被调用了"+System.currentTimeMillis());
	}
	/**
	 * 在当前控件的父控件中画出当前控件
	 */
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		System.out.println("onDraw 我被调用了"+System.currentTimeMillis()); 
	}
}

二:布局文件

<com.yin.test.MyImageView 
        android:id="@+id/iv"
        android:layout_below="@id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/android_normal"/>

三:获取宽高的三种方法

public class MainActivity extends Activity {
	/**
	 * 方法调用顺序测试
	 */
//	@Override
//	protected void onCreate(Bundle savedInstanceState) {
//		super.onCreate(savedInstanceState);
//		setContentView(R.layout.activity_main);
//		MyImageView iv = (MyImageView) findViewById(R.id.iv);
//		System.out.println("执行完毕.."+System.currentTimeMillis()); 
//		/**
//		 * 执行结果
//		 执行完毕..1435593788788
//		onMeasure 我被调用了1435593788812
//		onMeasure 我被调用了1435593788812
//		onMeasure 我被调用了1435593788851
//		onMeasure 我被调用了1435593788851
//		onDraw 我被调用了1435593788853
//	结果分析:因为等onCreate方法执行完后,控件才开始度量长宽,因此,无法再onCreate方法中获取控件的长和宽
//		 */
//	}
	/**
	 * 获取控件宽高的第一种方法
	 * 执行结果:
	 * onMeasure 我被调用了1435594709480
		宽:242,高:245**
		执行完毕..1435594709481
		onMeasure 我被调用了1435594709591
		onMeasure 我被调用了1435594709592
		onMeasure 我被调用了1435594710416
		onMeasure 我被调用了1435594710416
		onDraw 我被调用了1435594710419
	 */
//	@Override
//	protected void onCreate(Bundle savedInstanceState) {
//		super.onCreate(savedInstanceState);
//		setContentView(R.layout.activity_main);
//		MyImageView imageView = (MyImageView) findViewById(R.id.iv);
//		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();  
//	      System.out.println("宽:"+width+",高:"+height+"**");  
//	        
//	      System.out.println("执行完毕.."+System.currentTimeMillis());
//	}
	
	/**
	 * 获取控件宽高的第二种方法
	 * 执行结果:
	 *  执行完毕..1435595234983
 		onMeasure 我被调用了1435595235018
 		onMeasure 我被调用了1435595235019
 		宽:242,高:245**
 		onMeasure 我被调用了1435595235094
 		onMeasure 我被调用了1435595235094
 		宽:242,高:245**
 		onDraw 我被调用了1435595235097
 	结果分析:先执行完onCreate方法再执行onMeasure,说明该方法是通过回调的方式获取控件的宽高,且会多次获取宽高
	 */
//	@Override
//	protected void onCreate(Bundle savedInstanceState) {
//		super.onCreate(savedInstanceState);
//		setContentView(R.layout.activity_main);
//		final MyImageView imageView = (MyImageView) findViewById(R.id.iv);
//		ViewTreeObserver vto = imageView.getViewTreeObserver();  
//	    vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {  
//	        public boolean onPreDraw() {  
//	            int height = imageView.getMeasuredHeight();  
//	            int width = imageView.getMeasuredWidth();  
//	            System.out.println("宽:"+width+",高:"+height+"**"); 
//	            return true;  
//	        }  
//	    });
//	    System.out.println("执行完毕.."+System.currentTimeMillis());
//	}
	
	/**
	 * 获取控件宽高的第三种方法
	 * 执行结果:
	 *  执行完毕..1435595905110
 		onMeasure 我被调用了1435595905202
 		onMeasure 我被调用了1435595905203
 		高:245,宽:242
 		onMeasure 我被调用了1435595905388
 		onMeasure 我被调用了1435595905389
 		onDraw 我被调用了1435595905391
 		onDraw 我被调用了1435595908050
 	结果分析:该方法与方法二大致相同,都是通过回调的方式,在onCreate执行完后,再获取控件的宽高,且只获取一次宽高
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		final MyImageView imageView = (MyImageView) findViewById(R.id.iv);
		ViewTreeObserver vto2 = imageView.getViewTreeObserver();    
	    vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {  
	        @Override    
	        public void onGlobalLayout() {  
	            imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);    
	            System.out.println("\n\n"+"高:"+imageView.getHeight()+",宽:"+imageView.getWidth());  
	        }    
	    });
	    System.out.println("执行完毕.."+System.currentTimeMillis());
	}
}

四:第三种方法的总结

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		imageView = (MyImageView) findViewById(R.id.iv);
		System.out.println(
				"\n\n"+"onCreate方法中调用getLayoutParams方法ImageView的宽100dp:"+imageView.getLayoutParams().width+
				",onCreate方法中调用getLayoutParams方法ImageView的高wrap_content:"+imageView.getLayoutParams().height);
		
		System.out.println(
				"\n\n"+"onCreate方法中调用getWidth()时ImageView的宽100dp:"+imageView.getWidth()+
				",onCreate方法中调用getHeight()时ImageView的高wrap_content:"+imageView.getHeight());
		tv = (TextView) findViewById(R.id.tv);
		System.out.println(
				"onCreate方法中调用getLayoutParams方法TextView的宽30dp:"+tv.getLayoutParams().width+
				",onCreate方法中调用getLayoutParams方法TextView的高60dp:"+tv.getLayoutParams().height);
		System.out.println(
				 "onCreate方法中调用getWidth()时TextView的宽30dp:"+tv.getWidth()+
				",onCreate方法中调用getHeight()方法TextView的高60dp:"+tv.getHeight());
        LayoutParams lp = tv.getLayoutParams();
        lp.width = 200;
        lp.height = 400;
        tv.setLayoutParams(lp);
		System.out.println("------------------------onCreate中---------------------------------");
		ViewTreeObserver vto2 = imageView.getViewTreeObserver();    
	    vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {  

			@Override    
	        public void onGlobalLayout() {  
	            imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);    
	    		System.out.println(
	    				"\n\n"+"onCreate方法执行完成后调用getLayoutParams方法ImageView的宽100dp:"+imageView.getLayoutParams().width+
	    				",onCreate方法执行完成后调用getLayoutParams方法ImageView的高wrap_content:"+imageView.getLayoutParams().height);
	    		
	    		System.out.println(
	    				"\n\n"+"onCreate方法执行完成后调用getWidth()时ImageView的宽100dp:"+imageView.getWidth()+
	    				",onCreate方法执行完成后调用getHeight()时ImageView的高wrap_content:"+imageView.getHeight());
	    		System.out.println(
	    				"onCreate方法执行完成后调用getLayoutParams方法TextView的宽30dp:"+tv.getLayoutParams().width+
	    				",onCreate方法执行完成后调用getLayoutParams方法TextView的高60dp:"+tv.getLayoutParams().height);
	    		System.out.println(
	    				 "onCreate方法执行完成后调用getWidth()时TextView的宽30dp:"+tv.getWidth()+
	    				",onCreate方法执行完成后调用getHeight()方法TextView的高60dp:"+tv.getHeight());	            
	    		System.out.println("------------------------onCreate后---------------------------------");	            
	            
//	            ivHeight = imageView.getHeight();
//	            ivWidth = imageView.getWidth();
//	            LayoutParams lp = tv.getLayoutParams();
//	            lp.width = 100;
//	            lp.height = 200;
//	            lp.width = imageView.getWidth();
//	            lp.height = imageView.getHeight();
	            
//	            tv.setLayoutParams(lp);
//	            tv.setWidth(imageView.getWidth());这种方式无效
//	            tv.setHeight(imageView.getHeight());
	        }    
	    });
	    System.out.println("执行完毕.."+System.currentTimeMillis());
	}
	@Override
	protected void onStart() {
		super.onStart();
		System.out.println(
				"\n\n"+"onStart方法执行完成后调用getLayoutParams方法ImageView的宽100dp:"+imageView.getLayoutParams().width+
				",onStart方法执行完成后调用getLayoutParams方法ImageView的高wrap_content:"+imageView.getLayoutParams().height);
		
		System.out.println(
				"\n\n"+"onStart方法执行完成后调用getWidth()时ImageView的宽100dp:"+imageView.getWidth()+
				",onStart方法执行完成后调用getHeight()时ImageView的高wrap_content:"+imageView.getHeight());
		System.out.println(
				"onStart方法执行完成后调用getLayoutParams方法TextView的宽30dp:"+tv.getLayoutParams().width+
				",onStart方法执行完成后调用getLayoutParams方法TextView的高60dp:"+tv.getLayoutParams().height);
		System.out.println(
				 "onStart方法执行完成后调用getWidth()时TextView的宽30dp:"+tv.getWidth()+
				",onStart方法执行完成后调用getHeight()方法TextView的高60dp:"+tv.getHeight());	            
		System.out.println("------------------------onStart中---------------------------------");			
	}
	@Override
	protected void onResume() {
		super.onResume();
		System.out.println(
				"\n\n"+"onResume方法执行完成后调用getLayoutParams方法ImageView的宽100dp:"+imageView.getLayoutParams().width+
				",onResume方法执行完成后调用getLayoutParams方法ImageView的高wrap_content:"+imageView.getLayoutParams().height);
		
		System.out.println(
				"\n\n"+"onResume方法执行完成后调用getWidth()时ImageView的宽100dp:"+imageView.getWidth()+
				",onResume方法执行完成后调用getHeight()时ImageView的高wrap_content:"+imageView.getHeight());
		System.out.println(
				"onResume方法执行完成后调用getLayoutParams方法TextView的宽30dp:"+tv.getLayoutParams().width+
				",onResume方法执行完成后调用getLayoutParams方法TextView的高60dp:"+tv.getLayoutParams().height);
		System.out.println(
				 "onResume方法执行完成后调用getWidth()时TextView的宽30dp:"+tv.getWidth()+
				",onResume方法执行完成后调用getHeight()方法TextView的高60dp:"+tv.getHeight());	            
		System.out.println("------------------------onResume中---------------------------------");			
	}


第三种方法运行结果规律:
规律一:
onCreate()中:
View.getLayoutParams().width/height:
如果在布局文件中View的width/height是具体的值(dp/px)则可以取到,且取值结果是像素(如果是dp则会自动转换为px);
如果在布局文件中View的width/height不是具体的值,而是wrap_content/fill_parent等时,则取不到值,且结果是负数(-2?)
View.getWidth()/getHeight():
不论布局文件中View的width/height是不是具体的值,其结果都是0,即取不到值。
规律二:
onStart()中:
情况和onCreate()方法相同,且在OnGlobalLayoutListener.onGlobalLayout()方法之前执行。
规律三:
onResume()中:
情况和onCreate()方法相同,且在OnGlobalLayoutListener.onGlobalLayout()方法之前执行。
规律四:
OnGlobalLayoutListener.onGlobalLayout()中:
View.getLayoutParams().width/height:和onCreate()方法相同
如果在布局文件中View的width/height是具体的值(dp/px)则可以取到,且取值结果是像素(如果是dp则会自动转换为px);
如果在布局文件中View的width/height不是具体的值,而是wrap_content/fill_parent等时,则取不到值,且结果是负数(-2?)
View.getWidth()/getHeight():
不论布局文件中View的width/height是不是具体的值,都能取到值,且结果的单位是像素
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值