【Android】获取View宽高的问题

在Android中,直接获取View的宽高可能得到0,因为UI布局未完成。可以使用ViewTreeObserver监听绘制事件,View.post()在布局完成后执行,或者重写onLayout方法。同时介绍了检查布局完成的方法和获取静态定义宽高的方式。
摘要由CSDN通过智能技术生成

关于如何在获取View的宽高

如果直接在 onCreate() 中获取View的宽高的话会直接返回0,甚至在 onResume() 中也是这样,因为这个时候 UI 界面布局还未完成。要获取View的宽高参数必须要的等到绘制过程完成(特别是一些动态的参数 wrap_contentmatch_parent),但是通常在 onResume() 时还未完成,所以需要等到绘制过程完全结束。

监听绘制事件:ViewTreeObserver

ViewTreeObserver 将被各种绘制事件触发,通常 OnGlobalLayoutListener 就是用来监听测量结果的,这里的代码将在测量结束时调用。

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
	@Override
	public void onGlobalLayout() {
		view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
		view.getHeight(); 
	}
});

注意:这个监听用完必须立即移除,否则将被每个布局事件触发。

布局队列中添加线程 View.post()

只需要在 View 的 post() 方法中添加runnable实现。添加到这个队列的代码基本上会在 View 的 measure() layout()等方法结束之后调用。

UI事件队列将顺序的处理。在 setContentView() 被调用之后,这个事件队列将包含要求重新布局的消息,所以添加到这个队列的代码将在布局完成之后被调用。

view.post(new Runnable() {
	@Override
	public void run() {
	   view.getHeight();
	}
});

比 ViewTreeObserver: 需要在代码执行完后取消观察者(并且可能会忘记)更加方便,语法也简洁。

重写 View 的 onLayout 方法

只有当其他代码逻辑可以被封装在view内部才会显得实用。

view = new View(this) {
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
       	view.getHeight();
    }
};

注意: onLayout() 将被多次调用,所以要清楚自己的方法做了什么 会影响什么,或者考虑只让代码执行一次:

if(isFirst){
	view.getHeight();
}

检查是否布局完成

如果代码将在创建 UI 界面的时候多次执行,可以考虑如下的方法:

// view : 需要被测量宽高
if(ViewCompat.isLaidOut(view)) {
	view.getHeight();
}

在到达或离开屏幕后 view 至少一次被布局之后,ifViewCompat.isLaidOut(view) 将返回 true

获取静态定义的值

如果定义的静态宽或高的值就足够了,可以简单的使用:

View.getMeasuredWidth()
View.getMeasuredHeigth()

注意:这个值可能会与绘制后实际的值不同。

本篇完全是翻译了
参考资料:
Stack Overflow

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值