Android获取控件大小的方法

来源:互联网 发布:域名主机 编辑:程序博客网 时间:2024/05/22 07:50
在Android中很多时候都需要获取到控件的大小,这样对于布局的计算有许多的帮助,比如一个GridView布置成多少行多少列是需要提前知道自己允许的最大的高度和宽度才能计算,这样就需要得到控件的大小。控件的大小是在View的measure的过程计算出来的。所有我们如果通过直接在onCreate()、onResume()等等方法中直接去取控件的大小是取不到的。而这里面的原因是View的measure过程和Activity的生命周期是不同步的,也就是说无法保证Activity中的onCreate()等等执行的时候View的measure()已经执行了,如果此时还没有执行肯定是得不到值的。
那么到底有没有得到控件大小的方法,答案肯定是有的。实现的方法分为两大类:
1.View在执行measure()方法之后
     这是很好理解的部分,等到View已经measure()了,我们当然能很方便的得到View的大小。
     (1)Activity中的View.Callback中的onWindowFocusChanged(),在Activity中实现这个方法就可以获取到空间的大小了。(PS:该方法会在Activity每次执行onResume()或者onPause()都执行)
public void onWindowFocusChanged(boolean hasFocus){    if(hasFocus){        int height = view.getHeight();        int width = view.getWidth();    }}
         (2)使用ViewTreeObserver的很多的回调接口。例如使用OnGlobalLayoutListener,当View树的状态发生变化或者View叔内部的View的可见性发生改变时。(PS:View树改变的时候,onGlobalLayout会被调用多次)
@Overrideprotected void onStart() {    super.onStart();    textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {          @Override        public void onGlobalLayout() {             int height = view.getHeight();            int width = view.getWidth();                           }    });}
     (3)通过View的post()方法将一个runnable发送到消息队列尾部,当该runnable执行的时候,此时的View已经初始化好了,可以得出View的大小。
@Overrideprotected void onStart() {    super.onStart();    textView.post(new Runnable() {        @Override        public void run() {            int width = textView.getMeasuredWidth();            int height = textView.getMeasuredHeight();            System.out.println("Egos" + width + " " + height);        }    });}
2.View在执行measure()方法之前
也就是说一定要在onCreate()等方法中来获取控件的大小,可以知道View的measure过程是得到控件的大小,所以思路是可以通过手动measure来获取控件的大小。但其实手动measure的方式得到控件的大小不一定每次都是正确的。需要根据布局文件中控件设置的大小的情况来讨论。
a.match_parent
这种情况无法得到控件的大小,因为此时还需要考虑parent的布局才能计算出该控件的大小。
b.固定的大小(dp/px)
例如:控件设置的是100dp
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(context.getResources().getDisplayMetrics().density *100,MeasureSpec.EXACTLY);int heightMeasureSpec = MeasureSpec.makeMeasureSpec(context.getResources().getDisplayMetrics().density *100,MeasureSpec.EXACTLY);view.measure(widthMeasureSpec,heightMeasureSpec);int width = view.getMeasureWidth();int height = view.getMeasureHeight();
c.wrap_content(网上得到的据说最正确的写法)
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST);int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST);view.measure(widthMeasureSpec,heightMeasureSpec);
ps:方法来自网络和书籍,有什么错误之处希望你
0 0