close

在看一個 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 簡單來說就是用戶在做觸屏操作時的模式

點擊我看 官方的 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

 


arrow
arrow
    創作者介紹
    創作者 顏澤偉 的頭像
    顏澤偉

    Willy's Fish教學筆記』

    顏澤偉 發表在 痞客邦 留言(0) 人氣()