1. 程式人生 > >Android view變化監聽器 ViewTreeObserver( oncreate獲取view資訊)

Android view變化監聽器 ViewTreeObserver( oncreate獲取view資訊)

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);