在看一個 UI 庫原碼時
看到了一個監聽的類 ViewTreeObserver
今天我們就來介紹一下此 class 吧。
Observer 的設計模式大家多少都有看過
不知道的可以點這裡 ( 尚未po上blog… )
而這一個 ViewTreeObserver 就是針對 View 的行為做訂閱的 Observer
class 裡頭有很多方法可以添加 Listener 如( removeXXXXXXListener、addXXXXXXListener… )
那麼此類的 Listener 有哪些呢?
請看下表,這裡有很多的 interface Listener 可供我們使用
onDrawListener
在我們的 view tree 要渲染時 callback
onGlobalFocusLayoutListener
在 view tree 的焦點改變時 callback
onGlobalLayoutListener
在 view tree 之中的 view 有改變狀態或可見性時 callback
onPreDrawListener
比 onDrawListener 還早一點 callback
onScrollChangedListener
在 view tree 之中的 view 有滾動時 callback
onTouchModeChangeListener
在 view 的 TouchMode 改變時 callback
TouchMode 簡單來說就是用戶在做觸屏操作時的模式
onWindowAttachListener
在 view 層向 window 層 attached and detached 的時候 callback
onWindowFocusChangeListener
在 window 層的焦點改變時 callback
看完了各個 Listener 的用途之後
來說說我們常遇到的一個問題吧,就是 View 寬高的取得
各位看倌們是不是曾遇到過值為 0 的問題呢?
那是因為 View 還沒有 Measure 的關係
在 onCreat 的時候 view 還沒有定型
在 onResume 的時候就可以取得值了
那若是想要在 onCreat 取得 view 的寬高呢?
那就可以試試用 ViewTreeObserver
以下代碼可以幫助到您,大家快去試試吧 !!
// 取得ViewTreeObserver
final ViewTreeObserver mObserver = imageMain.getViewTreeObserver();
// 注冊Listener
mObserver.addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// ViewTreeObserver 若是 alive,remove Listener 以免重覆呼叫
if (mObserver.isAlive()) {
mObserver.removeGlobalOnLayoutListener(this);
}
// 取得寬高
int viewWidth = imageMain.getMeasuredWidth();
int viewHeight = imageMain.getMeasuredHeight();
}
}
);
參考資料:
https://developer.android.com/reference/android/view/ViewTreeObserver