ViewTreeObserver源码学习

一、理解ViewTreeObserver概念

ViewTreeObserver用来注册监听器,在视图树全局发生变化时收到通知。它不能被应用实例化,因为它是由视图提供,通过android.view.View#getViewTreeObserver()来获取。

ViewTree:视图树。在Android中,所有视图由View和View的子类组成。ViewGroup也是view的子类,它是View的容器,它可以装载View和ViewGroup。这样ViewGroup和View以树形结构一层一层的嵌套组合,就形成了视图树。

Observer:观察者。使用了观察者的设计模式,在这里,即ViewTree时被观察者,ViewTreeObserver是观察者,通过ViewTreeObserver注册监听来观察ViewTree的变化,当ViewTree发生变化,就会调用ViewTreeObserver的相关方法来通知其这一改变。我们可以在ViewTreeObserver中add自己的监听器,从而得到ViewTree的某一变化的通知做出自己的逻辑处理。

二、如何获取ViewTreeObserver

ViewTreeObserver是不能被应用程序实例化的,因为它是由视图提供的,通过view.getViewTreeObserver()获取。

//View.java

public ViewTreeObserver getViewTreeObserver() {
    if (mAttachInfo != null) {
        return mAttachInfo.mTreeObserver;
    }
    if (mFloatingTreeObserver == null) {
        mFloatingTreeObserver = new ViewTreeObserver();
    }
    return mFloatingTreeObserver;
}

其中,AttachInfo是View的一个内部类。当一个View附着到它的父Window中时,这个View能获取到一组View和父Window之间的信息,就存储在AttachInfo当中。AttachInfo中就有一个ViewTreeObserver对象。当mAttachInfo为空时,返回mFloatingTreeObserver,一个特殊的ViewTreeObserver。

那么,每一个view的mAttachInfo是怎么获取到的呢?AttachInfo是在View第一次attach到Window时,ViewRoot传给自己的子View的,然后沿着视图树,AttachInfo会一直传递到每一个View。

//ViewGroup.java

@Override
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
      ...
    final int count = mChildrenCount;
    final View[] children = mChildren;
    for (int i = 0; i < count; i++) {
        final View child = children[i];
        child.dispatchAttachedToWindow(info,
                combineVisibility(visibility, child.getVisibility()));
    }
    ...
}

//View.java

void dispatchAttachedToWindow(AttachInfo info, int visibility) {
    //System.out.println("Attached! " + this);
    mAttachInfo = info;
    ...
}

另外,当新的View加入到ViewGroup中时,也会将AttachInfo传入。

//ViewGroup.java

private void addViewInner(View child, int index, LayoutParams params,
        boolean preventRequestLayout) {
    ...
    AttachInfo ai = mAttachInfo;
    if (ai != null && (mGroupFlags & FLAG_PREVENT_DISPATCH_ATTACHED_TO_WI
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值