2016-06-09
4:24 PM
VISIBLE, INVISIBLE 以及 GONE
這三種的差異在哪呢?
以下將針對差異的部分做一個簡單又稍微有點深入的說明
應該能在各位設定可視狀態時做一個參考
第一點:看得見與看不見的差異
當 View 被設定為 VISIBLE 就表示他是可見的,
在父層級(也就是 ViewGroup)在做 onLayout 與 onMeasure 動作時都會呼叫子 View 的 onLayout 與 onMeasure 動作
也會做所有的 onDraw 動作
這就表示會在螢幕上佔據一個空間
並將與其相對的所有 View 做一個相對位置(若有的話)的運算
然後將所有的變化經由 onDraw 畫出來
當 View 被設定為 INVISIBLE 時表示他是不可見的。
也同樣會做 onLayout 與 onMeasure 的動作
但不會做 onDraw 的動作
因此雖然會在螢幕上佔據一個空間並保有與其他 View 的相對位置
但看不見任何東西在螢幕上面
若 View 設定為 GONE 也同樣表示不可見
但此同時他也不會做任何的 onLayout 、 onMeasure 以及 onDraw 的動作
因此他不會具有相對位置的計算
也不會佔有任何空間
第二點:效能上的差異
在螢幕大小改變或是初始化時 Android 都會呼叫各個 View、ViewGroup 做 onMeasure 及 onLayout 的動作
若沒有這些情況發生,通常只會做一輪這個動作(其中同一個 View 的 onMeasure 會呼叫非常非常多次 但 onLayout 次數通常只有一次)
如果發生了螢幕大小改變(例如設定鍵盤出現時將畫面縮小)
就會重新做一輪這個動作(有時 onLayout 會做兩次或以上)
因此請將這個 onMeasure 及 onLayout 行為當作非常耗時的動作並謹慎看待(事實上也是)
並仔細設計 Layout 的結構
讓這些動作運算的時間盡量少一點
或是將不必要的 View 設定為 Gone 而略過這些動作
而重點就在這裡
如果你有一個 View 經常在看得見與看不見之間來回切換
這時你會選擇設定為 INVISIBLE 還是 GONE?
有人會問說 這有什麼差別?
事實上差別可大了
若你選擇使用 GONE
那麼這個 View 會在可視狀態切換時重新呼叫 onMeasure 以及 onLayout
並且是從這個 View 的父層級開始呼叫(往上幾層倒是不確定)
也就是說假如你有一個 ViewGroup 裡面包含了十個 View
那麼當其中一個 View 在 VISIBLE 跟 GONE 之間切換時
將會呼叫 ViewGroup 及所有 View 的 onMeasure 及 onLayout
因此這時如果有一個動畫的展示
很可能會造成這個動畫有 lag 的情形發生
換言之若選擇使用 INVISIBLE
那麼在可視狀態切換時並不會重新呼叫這一大堆的 onMeasure 及 onLayout
也就是說如果在這時有動畫的展示
看起還會比使用 GONE 切換來得順暢一點
有人就會覺得 那乾脆全部用 INVISIBLE 不就好了?
但就像前面提到的
如果螢幕大小發生變化 INVISIBLE 的 View 也同樣需要重新 onMeasure 及 onLayout
反而這時使用 GONE 會是比較好的選擇
因此在這兩者之間要如何斟酌就要看使用者自己的評估了
如果是常常在狀態間切換用的 View 其實可以設定為 INVISIBLE 狀態
反之如果是偶爾才出現一次的 View 就可以設定為 GONE 來略過不必要的 onMeasure 及 onLayout 過程