View[5] ViewTreeObserver

来源:互联网 发布:单片机排针怎么用 编辑:程序博客网 时间:2024/05/17 10:39

【参考链接】

 

View类提供了getViewTreeObserver()方法来获取一个ViewTreeObserver对象

通过给这个对象add各种Listener,可以实现相关情况的回调,并且在使用完成以后remove()掉。

是一个观察者模式的实现。



不过实验的时候,调用viewscrollTo()/scrollBy()并未触发onScrollChangedListener.

 

需要注意的是

1、在视图树中的任何View使用getViewTreeObserver(),获取到的都是同一个ViewTreeObserver对象


2、在使用ViewTreeObserver对象前最好通过isAlive()方法进行判断其是否还alive

 

以如下代码为例

finalViewTreeObserver viewTreeObserver =tv.getViewTreeObserver();
if
(viewTreeObserver.isAlive())
   viewTreeObserver.addOnTouchModeChangeListener(
newViewTreeObserver.OnTouchModeChangeListener(){
       
@Override
       
public voidonTouchModeChanged(booleanb) {
           Log.e(
"ViewTreeObserverX","onTouchModeChanged()");
       
}
    })
;

if
(viewTreeObserver.isAlive())
   viewTreeObserver.addOnGlobalFocusChangeListener(
newViewTreeObserver.OnGlobalFocusChangeListener(){
       
@Override
       
public voidonGlobalFocusChanged(View view,View view1) {
           Log.e(
"ViewTreeObserverX","onGlobalFocusChanged()");
       
}
    })
;

if
(viewTreeObserver.isAlive())
   viewTreeObserver.addOnGlobalLayoutListener(
newViewTreeObserver.OnGlobalLayoutListener(){
       
@Override
       
public voidonGlobalLayout() {
           Log.e(
"ViewTreeObserverX","onGlobalLayout()");
       
}
    })
;

if
(viewTreeObserver.isAlive())
   viewTreeObserver.addOnPreDrawListener(
newViewTreeObserver.OnPreDrawListener() {
       
@Override
        
public booleanonPreDraw() {

           Log.e(
"ViewTreeObserverX","onPreDraw()");
           if
(viewTreeObserver.isAlive())
               
viewTreeObserver.removeOnPreDrawListener(this);
           else
               
tv.getViewTreeObserver().removeOnPreDrawListener(this);

           return false;
       
}
    })
;

if
(viewTreeObserver.isAlive())
   viewTreeObserver.addOnScrollChangedListener(
newViewTreeObserver.OnScrollChangedListener(){
       
@Override
       
public voidonScrollChanged() {
           Log.e(
"ViewTreeObserverX","onScrollChanged()");
       
}
    })
;

 

在整个流程中的调用时机如下

onGlobalLayout()为例,可以在其中去获取View的长宽的和位置


 

原创粉丝点击