Search

Android - VISIBLE INVISIBLE 及 GONE 的差異

2016-06-09 4:24 PM
Android 的 View 有三種可視狀態

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 過程