ViewTreeObserver 监听整个视图发生的变化情况

本文介绍如何利用ViewTreeObserver.OnGlobalLayoutListener接口,在视图完成布局后获取控件的实际高度,实现控件间的高度适配。通过注册监听器并在布局完成后注销,避免多次回调。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在项目中有这样一个需求,我的某一个控件需要根据其他控件的高度来确定自己的高度,以达到适配的效果。因此,我需要在整个视图完成布局之后,就获得这些高度的参数,在网上搜索了资料后发现,ViewTreeObserver可以完成这样的功能任务。
ViewTreeObserver是一个视图树的观察者,只要视图发生且不局限于以下几个方面的变化时,都会有回调:整个视图树的布局变化,开始绘制视图,触摸模式改变等等。
ViewTreeObserver里面有很多内部类,大都是针对于不同情况变化的回调接口,我们这里要说的interface ViewTreeObserver.OnGlobalFocusChangeListener就是其中的一个内部接口。当视图的布局发生改变的时候,就会调用OnGlobalFocusChangeListener这个回调监听。
我们通过去ViewTreeObserver获取视图实际高度的时候,代码如下:

private void initOnLayoutListener() {
        final ViewTreeObserver viewTreeObserver = this.getWindow().getDecorView().getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                root_h = root_layout.getMeasuredHeight();
                actionbar_h = myactionbar.getMeasuredHeight();
                tabs_h = tabs.getMeasuredHeight();
                line_h = line.getMeasuredHeight();

                int height0 = root_h - actionbar_h - tabs_h - line_h;

                android.widget.RelativeLayout.LayoutParams param_map0 = 
                        new android.widget.RelativeLayout.LayoutParams
                        (android.widget.RelativeLayout.LayoutParams.MATCH_PARENT, height0);
                param_map0.addRule(RelativeLayout.BELOW, R.id.actionbar_layout);
                frame.setLayoutParams(param_map0);

                Log.i(TAG, "root_h:"+root_h);
                Log.i(TAG, "line_h:"+line_h);

                handler.sendEmptyMessage(0x1);
           // 移除GlobalLayoutListener监听     
              MainActivity.this.getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });
    }

//一般都是在oncreate()方法里面去注册该监听
@Override
    protected void onCreate(Bundle arg0) {
        super.onCreate(arg0);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        ninit();        
        initOnLayoutListener();
    }

需要注意的是,OnGlobalLayoutListener可能会被多次回调,因此,我们在获得了实际高度数据后,记得把监听注销掉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值