ViewTreeObserver結構
extends Object java.lang.Object ↳ android.view.ViewTreeObserver
ViewTreeObserver概述
A view tree observer is used to register listeners that can be notified of global changes in the view tree.
Such global events include, but are not limited to, layout of the whole tree, beginning of the drawing pass, touch mode change....
A ViewTreeObserver should never be instantiated by applications as it is provided by the views hierarchy.
Refer to getViewTreeObserver() for more information.
這個觀察者用來監聽視圖樹,會監聽視圖樹發生全局變化時發出的通知。這里指的全局事件包括而且不局限在以下幾個:整個視圖樹的布局變化,開始繪制視圖,觸摸模式改變等等。
ViewTreeObserver是不能被應用程序實例化的,因為它是由視圖提供的,通過view.getViewTreeObserver()獲取。詳情需要查看getViewTreeObserver()方法。
注:簡單的說,這是個view事件的觀察者。要注意的是它的初始化就是調用View.getViewTreeObserver()。
ViewTreeObserver內部類
interface | ViewTreeObserver.OnDrawListener | Interface definition for a callback to be invoked when the view tree is about to be drawn. 當在一個視圖樹繪制時,所要調用的回調函數的接口類 |
interface | ViewTreeObserver.OnGlobalFocusChangeListener | Interface definition for a callback to be invoked when the focus state within the view tree changes. 當在一個視圖樹中的焦點狀態發生改變時,所要調用的回調函數的接口類 |
interface | ViewTreeObserver.OnGlobalLayoutListener | Interface definition for a callback to be invoked when the global layout state or the visibility of views within the view tree changes. 當在一個視圖樹中全局布局發生改變或者視圖樹中的某個視圖的可視狀態發生改變時,所要調用的回調函數的接口類 |
interface | ViewTreeObserver.OnPreDrawListener | Interface definition for a callback to be invoked when the view tree is about to be drawn. 當一個視圖樹將要繪制時,所要調用的回調函數的接口類 |
interface | ViewTreeObserver.OnScrollChangedListener | Interface definition for a callback to be invoked when something in the view tree has been scrolled. 當一個視圖樹中的一些組件發生滾動時,所要調用的回調函數的接口類 |
interface | ViewTreeObserver.OnTouchModeChangeListener | Interface definition for a callback to be invoked when the touch mode changes. 當一個視圖樹的觸摸模式發生改變時,所要調用的回調函數的接口類 |
ViewTreeObserver公共方法
1.public void addOnDrawListener (ViewTreeObserver.OnDrawListener listener)
/**注冊一個回調函數,當在一個視圖樹繪制時調用這個回調函數。 * 參數 listener 將要被添加的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
2.public void addOnGlobalFocusChangeListener (ViewTreeObserver.OnGlobalFocusChangeListener listener)
/**注冊一個回調函數,當在一個視圖樹中的焦點狀態發生改變時調用這個回調函數。 * 參數 listener 將要被添加的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
3.public void addOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener listener)
/**注冊一個回調函數,當在一個視圖樹中全局布局發生改變或者視圖樹中的某個視圖的可視狀態發生改變時調用這個回調函數。 *參數 listener 將要被添加的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
4.public void addOnPreDrawListener (ViewTreeObserver.OnPreDrawListener listener)
/**注冊一個回調函數,當一個視圖樹將要繪制時調用這個回調函數。 *參數 listener 將要被添加的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
5.public void addOnScrollChangedListener (ViewTreeObserver.OnScrollChangedListener listener)
/**注冊一個回調函數,當一個視圖發生滾動時調用這個回調函數。 *參數 listener 將要被添加的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
6.public void addOnTouchModeChangeListener (ViewTreeObserver.OnTouch3.監聽焦點的變化ModeChangeListener listener)
/**注冊一個回調函數,當一個觸摸模式發生改變時調用這個回調函數。 *參數 listener 將要被添加的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
7.public final void dispatchOnDraw ()
//告知相應監聽器,視圖繪制開始了
8.public final void dispatchOnGlobalLayout ()
//當整個布局發生改變時通知相應的注冊監聽器。如果你強制對視圖布局或者在一個沒有附加到一個窗口的視圖的層次結構或者在GONE狀態下,它可以被手動的調用
9.public final boolean dispatchOnPreDraw ()
/**當一個視圖樹將要繪制時通知相應的注冊監聽器。如果這個監聽器返回true,則這個繪制將被取消並重新計划。如果你強制對視圖布局或者在一個沒有附加到一個窗口的視圖的層次結構或者在一個GONE狀態下,它可以被手動的調用 *返回值 當前繪制能夠取消並重新計划則返回true,否則返回false。 */
10.public boolean isAlive ()
/**指示當前的ViewTreeObserver是否可用(alive)。當observer不可用時,任何方法的調用(除了這個方法)都將拋出一個異常。如果一個應用程序保持和ViewTreeObserver一個歷時較長的引用,它應該總是需要在調用別的方法之前去檢測這個方法的返回值。 *返回值 但這個對象可用則返回true,否則返回false */
11.public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
/**移除之前已經注冊的全局布局回調函數。 *參數 victim 將要被移除的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
12.public void removeOnDrawListener (ViewTreeObserver.OnDrawListener victim)
/**移除之前已經注冊的視圖繪制回調函數。 *參數 victim 將要被移除的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
13.public void removeOnGlobalFocusChangeListener (ViewTreeObserver.OnGlobalFocusChangeListener victim)
/**移除之前已經注冊的焦點改變回調函數。 *參數 victim 將要被移除的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
14.public void removeOnPreDrawListener (ViewTreeObserver.OnPreDrawListener victim)
/**移除之前已經注冊的預繪制回調函數。 *參數 victim 將要被移除的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
15.public void removeOnScrollChangedListener (ViewTreeObserver.OnScrollChangedListener victim)
/**移除之前已經注冊的滾動改變回調函數。 *參數 victim 將要被移除的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
16.public void removeOnTouchModeChangeListener (ViewTreeObserver.OnTouchModeChangeListener victim)
/**移除之前已經注冊的觸摸模式改變回調函數 *參數 victim 將要被移除的回調函數 *異常 IllegalStateException 如果isAlive() 返回false */
ViewTreeObserver具體示例
1.在OnCreate()中獲取控件高度與寬度
ViewTreeObserver observer = view.getViewTreeObserver(); observer .addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { view.getViewTreeObserver().removeGlobalOnLayoutListener(this); final int w = view.getMeasuredWidth(); final int h = view.getMeasuredHeight(); } });
但是需要注意的是OnGlobalLayoutListener可能會被多次觸發,因此在得到了高度之后,要將OnGlobalLayoutListener注銷掉。
2.啟動幀動畫
OnPreDrawListener opdl=new OnPreDrawListener(){ @Override public boolean onPreDraw() { animDraw.start(); return true; } }; //onCreate方法中 imageV.getViewTreeObserver().addOnPreDrawListener(opdl);
3.監聽焦點的變化
// onGlobalFocusChanged 是接口 ViewTreeObserver.OnGlobalFocusChangeListener // 中定義的方法。 // 焦點發生變化時,會觸發這個方法的執行 @Override public void onGlobalFocusChanged(View oldFocus, ViewnewFocus) { if (oldFocus != null && newFocus!= null ) { tv_display .setText( "Focus /nFROM:/t" + oldFocus.toString() + "/n TO:/t" + newFocus.toString()); } }
需要注意的是,布局中的任何一個view添加了這個監聽,該布局的任意控件的焦點變化都能夠監聽的到。