【参考链接】

 

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

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

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

View[5] ViewTreeObserver

View[5] ViewTreeObserver

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

 

需要注意的是

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

View[5] ViewTreeObserver

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

 

以如下代码为例

final ViewTreeObserver viewTreeObserver = tv.getViewTreeObserver();
if
(viewTreeObserver.isAlive())
   viewTreeObserver.addOnTouchModeChangeListener(
new ViewTreeObserver.OnTouchModeChangeListener(){
       
@Override
       
public void onTouchModeChanged(boolean b) {
           Log.e(
"ViewTreeObserverX", "onTouchModeChanged()");
       
}
    })
;

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

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

if
(viewTreeObserver.isAlive())
   viewTreeObserver.addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
       
@Override
        
public boolean onPreDraw() {

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

           return false;
       
}
    })
;

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

 

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

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

View[5] ViewTreeObserver

 

相关文章:

  • 2022-12-23
  • 2021-12-18
  • 2022-03-08
  • 2021-06-04
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-19
猜你喜欢
  • 2022-12-23
  • 2021-12-25
  • 2022-12-23
  • 2022-12-23
  • 2021-04-01
相关资源
相似解决方案