android在代码中获取view宽/高为0解决方法

在项目中,我们要在代码中获取view的宽高信息,有可能就会在onCreat或者onResume方法中去获取,原因就是view的measure过程与Activity的生命周期不是同步执行的,因此无法保证在onCreat,onResume,onStart时这个view是否已经测量完毕,如果没有测量完毕,得到的结果就是0。这里给出4种解决办法

  • (1) onWindowFocusChanged
    onWindowFocusChanged含义就是view已经初始化完毕,这个时候去获取宽高就没问题了,但是要注意的是此方法会被调用很多次,当Activity的窗口失去或者得到焦点都会调用一次,也就是Activity onResume或onPause时都会调用。典型代码如下:
@Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus){
            int width = view.getMeasuredWidth();
            int height = view.getMeasuredHeight();
        }
    }
  • (2) view.post(runnable)
    通过post将一个runnable投递到消息队列的尾部,然后等Looper调用此runnable的时候,view也就已经初始化好了,典型代码如下:
@Override
    public void onStart() {
        super.onStart();
        view.post(new Runnable){
@Override
public void run(){
        int width = view.getMeasuredWidth();
        int height = view.getMeasuredHeight();
        }
    } 
}
  • (3) viewTreeObserver
    使用viewTreeObserver的众多回调可以完成这个功能,比如使用OnGlobalLayoutListener这个接口,当view树的状态发生改变或者view树的内部view的可见性发生改变时,onGlobalLayout方法会被调用,因此这是获取view宽高很好的时机。需要注意的是,伴随着view树状态改变onGlobalLayout会被调用很多次,典型代码如下:
@Override
    protected void onStart() {
        super.onStart();
        ViewTreeObserver observer = view.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
               int width = view.getMeasuredWidth();
        int height = view.getMeasuredHeight(); 
            }
        });
    }
  • (4) view.measure(intwidthMeasureSpec,intheightMeasureSpec)
    通过手动对view的measure来得到view的宽高,这种方法比较复杂,要分情况处理,根据view的LayoutParams来分:
  • math_parent
    无法测量,因为构造此种MeasureSpec需要知道parentSize,即父容器的剩余空间,而此时我们无法知道parentSize的大小,所以理论上测量不出view的大小。
  • 具体数值(dp/px)
    比如说宽高都是100px,如下:
int  widthMeasureSpec=MeasureSpec.makeMeasureSpec(100,MeasureSpec.EXACTLY);
int  heightMeasureSpec=MeasureSpec.makeMeasureSpec(100,MeasureSpec.EXACTLY);
view.measure(widthMeasureSpec,heightMeasureSpec);
  • wrap_content
int  widthMeasureSpec=MeasureSpec.makeMeasureSpec((1<<30)-1,MeasureSpec.AT_MOST);
int  heightMeasureSpec=MeasureSpec.makeMeasureSpec((1<<30)-1,MeasureSpec.AT_MOST);
view.measure(widthMeasureSpec,heightMeasureSpec);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值