ViewTreeObserver
public final class ViewTreeObserver extends Object
java.lang.Object
android.view.ViewTreeObserver
是一个注册监听视图树的观察者(observer),在视图树种全局事件改变时得到通知。这个全局事件不仅还包括整个树的布局,从绘画过程开始,触摸模式的改变等。ViewTreeObserver不能够被应用程序实例化,因为它是由视图提供getViewTreeObserver()
关于getViewTreeObserver()的解释
Returns the ViewTreeObserver for this view’s hierarchy. The view tree observer can be used to get notifications when global events, like layout, happen. The returned ViewTreeObserver observer is not guaranteed to remain valid for the lifetime of this View. If the caller of this method keeps a long-lived reference to ViewTreeObserver, it should always check for the return value of isAlive().
基本常用的方法:
//当在一个视图树中的焦点状态发生改变时,所要调用的回调函数的接口类
interfaceViewTreeObserver.OnGlobalFocusChangeListener
//当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时,所要调用的回调函数的接口类
interfaceViewTreeObserver.OnGlobalLayoutListener
//当一个视图树将要绘制时,所要调用的回调函数的接口类
interfaceViewTreeObserver.OnPreDrawListener
//当一个视图树中的一些组件发生滚动时,所要调用的回调函数的接口类
interfaceViewTreeObserver.OnScrollChangedListener
//当一个视图树的触摸模式发生改变时,所要调用的回调函数的接口类,用于监听 touch 和 非touch的转换
interfaceViewTreeObserver.OnTouchModeChangeListener
//用于监听布局之类的变化
interfaceViewTreeObserver.OnGlobalLayoutListener
// 当前ViewTreeObserver是否可用,不可用时,任何方法调用都会报错。
getViewTreeObserver().isAlive()
addOnWindowAttachListener
void removeOnGlobalFocusChangeListener()
void removeOnScrollChangedListener()
void removeOnTouchModeChangeListener()
//当整个布局发生改变时通知相应的注册监听器。如果你强制对视图布局或者在一个没有附加到一个窗口的视图的层次结构或者在GONE状态下,它可以被手动的调用
void dispatchOnGlobalLayout ()
//当一个视图树将要绘制时通知相应的注册监听器。如果这个监听器返回true,则这个绘制将被取消并重新计划。如果你强制对视图布局或者在一个没有附加到一个窗口的视图的层次结构或者在一个GONE状态下,它可以被手动的调用
void dispatchOnPreDraw()
1.实际用处解决onreate获取view 宽高
在oncreate无法获得一个view的高度和宽度
因为View组件布局要在onResume回调后完成。所以现在需要使用getViewTreeObserver().addOnGlobalLayoutListener()来获得宽度或者高度。这是获得一个view的宽度和高度的方法之一。
OnGlobalLayoutListener 是ViewTreeObserver的内部类,当一个视图树的布局发生改变时,可以被ViewTreeObserver监听到,这是一个注册监听视图树的观察者(observer),在视图树的全局事件改变时得到通知。ViewTreeObserver不能直接实例化,而是通过getViewTreeObserver()获得。
其中,我们可以利用OnGlobalLayoutListener来获得一个视图的真实高度。
private int imagePositionX ;
private int imagePositionY;
imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
imagePositionX = imageView.getX();
imagePositionY = imageView.getY();
imageWidth = imageView.getWidth();
imageHeight = imageView.getHeight();
//设置文本大小
tvInImage.setMaxWidth((int) imageWidth);
}
})
OnGlobalLayoutListener可能会被多次触发,因此在得到了高度之后,要将OnGlobalLayoutListener注销掉。
imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);