Android 获取控件的宽和高

原创 2012年08月07日 16:24:22


我们都知道在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


版权声明:本文为博主原创文章,未经博主允许不得转载。

获取控件的宽高和设置控件的宽高

转载地址:http://www.bkjia.com/Androidjc/890740.html 问题 如何获取一个控件的长和高,相信很多朋友第一眼看见这个问题都会觉得很简单,直...
  • qq_32399235
  • qq_32399235
  • 2016年05月24日 14:43
  • 717

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

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

笔记85--onCreate中获取控件宽和高

已找不到原作者。 常识:在onCreate()中获取的控件宽和高是0。因为onCreate()执行完了,我们定义的控件才会被度量。 方法一: 比其他的两个方法多了一次计算,也就是多调用了一次on...
  • mwj_88
  • mwj_88
  • 2014年11月26日 21:15
  • 635

android获取控件宽和高

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

动态的设置或者获取控件的长和宽

  • 2014年04月29日 18:25
  • 1.46MB
  • 下载

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

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

获取屏幕和控件的宽度和高度

获取屏幕和控件的宽度和高度
  • cheng900716lihai
  • cheng900716lihai
  • 2016年08月30日 16:58
  • 136

Android获取控件大小的方法

在Android中很多时候都需要获取到控件的大小,这样对于布局的计算有许多的帮助,比如一个GridView布置成多少行多少列是需要提前知道自己允许的最大的高度和宽度才能计算,这样就需要得到控件的大小。...
  • A38017032
  • A38017032
  • 2015年10月26日 21:27
  • 9291

动态获取和设置控件宽、高

问题 如何获取一个控件的长和高,相信很多朋友第一眼看见这个问题都会觉得很简单,直接在onCreate里面调用getWidth、getMeasuredWidth不就可以获得了吗,但是,事实上是并没有简...
  • baidu_28195399
  • baidu_28195399
  • 2015年09月08日 11:15
  • 809

android 获取控件的高度或者宽度。

开发的时候可能经常需要得到某个空间的高度或者宽度,比如一个textview,当你setText之后,就算你设置的再多的文字,调用getHeight方法他的高度也是为0(宽度同理)。这是因为view的绘...
  • robin_java
  • robin_java
  • 2016年06月03日 17:43
  • 3064
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 获取控件的宽和高
举报原因:
原因补充:

(最多只允许输入30个字)