Android 获取控件的宽和高

标签: android layout 控件 宽高
82185人阅读 评论(33) 收藏 举报
分类:


我们都知道在onCreate()里面获取控件的高度是0,这是为什么呢?我们来看一下示例:

首先我们自己写一个控件,这个控件非常简单:

public class MyImageView extends ImageView {

	public MyImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	public MyImageView(Context context) {
		super(context);
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		System.out.println("onMeasure 我被调用了"+System.currentTimeMillis());
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		System.out.println("onDraw 我被调用了"+System.currentTimeMillis());
	}

}


布局文件:

    <com.test.MyImageView
        android:id="@+id/imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/test" />

测试的Activity的onCreate():

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);        
        System.out.println("执行完毕.."+System.currentTimeMillis());
    }
现在我们现在来看一下结果:


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


现在碰到这个问题我们不能不解决,在网上找到了如下办法:

        //------------------------------------------------方法一
        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());
            }  
        });  

这三个方法是哪里找到现在已经忘了.


现在要讨论的是当我们需要时候使用哪个方法呢?

现在把测试的Activity改成如下:

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final ImageView imageView = (ImageView) findViewById(R.id.imageview);      
        
        //------------------------------------------------方法一
        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);
        
        System.out.println("执行完毕.."+System.currentTimeMillis());
    }



接着来看下面几种方式输出结果:

把测试Activity改成如下:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final ImageView imageView = (ImageView) findViewById(R.id.imageview);
		//-----------------------------------------------方法二
        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;
            }
        });
    }

结果如下:



方法三就不再测试了同方法二!!!


那么方法而和方法三在执行上有什么区别呢?

我们在布局文件中加入一个TextView来记录这个控件的宽高.

    <ScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </ScrollView>

先来测试方法而:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final ImageView imageView = (ImageView) findViewById(R.id.imageview);
		//-----------------------------------------------方法二
        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;
            }
        });
    }

结果如下:



我们再来测试方法三

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final ImageView imageView = (ImageView) findViewById(R.id.imageview);
        //-----------------------------------------------方法三   
        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的时候任然会调用,所以不建议使用.

方法三,比较合适.

当然,实际应用的时候需要根据实际情况而定.


谢谢!! 欢迎转载:http://blog.csdn.net/johnny901114/article/details/7839512


查看评论

[Visual Basic]VB源代码推荐: 动态的显示/隐藏start按钮

VB源代码推荐 : 动态的显示/隐藏start按钮 #VBIDEUtils#********************************************** * Programmer Na...
  • shines
  • shines
  • 2000-12-20 02:33:00
  • 1444

Android 中获取控件宽和高的方法(详细解析)

Android 中获取控件宽和高的方法第一种:直接获取getWidth()和getHeight() 我们都知道这两个方法在onCreate()方法中得到的数据都是0; 代码: mTextV...
  • CodeIsPoisonous
  • CodeIsPoisonous
  • 2017-01-10 17:40:44
  • 2173

最简单也最难——如何获取到Android控件的宽高

转自:http://www.2cto.com/kf/201410/341592.html 问题 如何获取一个控件的长和高,相信很多朋友第一眼看见这个问题都会觉得很简单,直接在onCreate里面调用g...
  • u011382177
  • u011382177
  • 2016-03-29 12:00:00
  • 3188

android获取控件宽高和屏幕宽高

一、获取屏幕宽高 要获取屏幕宽高,我们可以先从android的界面构成了解 android的界面主要由三部分构成:1、状态栏 2、标题栏 3、内容区域 1、状态栏 2、标题栏 android中标...
  • littlewhitetree
  • littlewhitetree
  • 2016-06-15 13:46:10
  • 6956

Android代码中如何获取控件宽高

源地址http://blog.csdn.net/nailsoul/article/details/25909313 在activity中可以调用View.getWidth、View.getHeight...
  • RuingMan
  • RuingMan
  • 2016-05-22 14:13:18
  • 7415

获取一个控件的高度与宽度的正确方法

获取一个控件的高度与宽度的正确方法我们知道在oncreate中View.getWidth和View.getHeight无法获得一个view的高度和宽度,这是因为View组件布局要在onResume回调...
  • u013293125
  • u013293125
  • 2017-08-11 13:31:49
  • 693

Android 中获取某个控件的宽高

获取控件的宽高
  • Greathfs
  • Greathfs
  • 2016-08-03 22:47:40
  • 11505

Android开发中获取屏幕宽高的几种方法

Android开发过程中经常会遇到获取手机屏幕宽高的需求,下面就获取屏幕宽高的方法总结如下:        方法1:利用WindowManager获取 int screenWidth = getWin...
  • biaobiao1217
  • biaobiao1217
  • 2015-07-14 13:54:16
  • 3189

android获取控件宽和高

Android获取控件宽高 在项目中用到了测量控件的宽和高,这个在Activity的onCreate去使用控件的getHeight()和getWidth()方法去获取是会失败的,返回的都是0。这是由于...
  • qq282330332
  • qq282330332
  • 2016-08-11 15:37:21
  • 749

android获取屏幕宽高与获取控件宽高

获取屏幕宽高// 获取屏幕宽高(方法1) int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素,...
  • chenguang79
  • chenguang79
  • 2013-07-02 10:50:40
  • 51475
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 100万+
    积分: 9139
    排名: 2579
    联系方式
    博客专栏
    最新评论