Android 全屏沉浸式應(yīng)用

2018-08-02 18:17 更新

編寫:K0ST - 原文:http://developer.android.com/training/system-ui/immersive.html

這節(jié)課將教您

  1. 選擇一種沉浸方式
  2. 使用非粘性沉浸模式
  3. 使用粘性沉浸模式

Adnroid 4.4(API level 19)中引入為setSystemUiVisibility()引入了一個新標(biāo)簽SYSTEM_UI_FLAG_IMMERSIVE,它可以讓應(yīng)用進入真正的全屏模式。當(dāng)這個標(biāo)簽與SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN一起使用的時候,導(dǎo)航欄和狀態(tài)欄就會隱藏,讓你的應(yīng)用可以接受屏幕上任何地方的觸摸事件。

當(dāng)沉浸式全屏模式啟用的時候,你的Activity會繼續(xù)接受各類的觸摸事件。用戶可以通過在邊緣區(qū)域向內(nèi)滑動來讓系統(tǒng)欄重新顯示。這個操作清空了SYSTEM_UI_FLAG_HIDE_NAVIGATION(和SYSTEM_UI_FLAG_FULLSCREEN,如果有的話)兩個標(biāo)簽,因此系統(tǒng)欄重新變得可見。如果設(shè)置了的話,這個操作同時也觸發(fā)了View.OnSystemUiVisibilityChangeListener。然而, 如果你想讓系統(tǒng)欄在一段時間后自動隱藏的話,你應(yīng)該使用SYSTEM_UI_FLAG_IMMERSIVE_STICKY標(biāo)簽。請注意,帶有'sticky'的標(biāo)簽不會觸發(fā)任何的監(jiān)聽器,因為在這個模式下展示的系統(tǒng)欄是處于暫時(transient)的狀態(tài)。

圖1展示了各種不同的“沉浸式”狀態(tài)

imm-states

圖1. 沉浸模式狀態(tài).

在上圖中:

  1. 非沉浸模式 —— 展示了應(yīng)用進入沉浸模式之前的狀態(tài)。也展示了設(shè)置IMMERSIVE標(biāo)簽后用戶滑動展示系統(tǒng)欄的狀態(tài)。用戶滑動后,SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN就會被清除,系統(tǒng)欄就會重新顯示并保持可見。 請注意,最好的實踐方式就是讓所有的UI控件的變化與系統(tǒng)欄的顯示隱藏保持同步,這樣可以減少屏幕顯示所處的狀態(tài),同時提供了更無縫平滑的用戶體驗。因此所有的UI控件跟隨系統(tǒng)欄一同顯示。一旦應(yīng)用進入了沉浸模式,相應(yīng)的UI控件也跟隨著系統(tǒng)欄一同隱藏。為了確保UI的可見性與系統(tǒng)欄保持一致,我們需要一個監(jiān)聽器View.OnSystemUiVisibilityChangeListener來監(jiān)聽系統(tǒng)欄的變化。這在下一節(jié)中將詳細講解。

  2. 提示氣泡——第一次進入沉浸模式時,系統(tǒng)將會顯示一個提示氣泡,提示用戶如何再讓系統(tǒng)欄顯示出來。

    Note:如果為了測試你想強制顯示提示氣泡,你可以先將應(yīng)用設(shè)為沉浸模式,然后按下電源鍵進入鎖屏模式,并在5秒中之后打開屏幕。

  3. 沉浸模式—— 這張圖展示了隱藏了系統(tǒng)欄和其他UI控件的狀態(tài)。你可以設(shè)置IMMERSIVEIMMERSIVE_STICKY來進入這個狀態(tài)。

  4. 粘性標(biāo)簽——這就是你設(shè)置了IMMERSIVE_STICKY標(biāo)簽時的UI狀態(tài),用戶會向內(nèi)滑動以展示系統(tǒng)欄。半透明的系統(tǒng)欄會臨時的進行顯示,一段時間后自動隱藏?;瑒拥牟僮鞑⒉粫蹇杖魏螛?biāo)簽,也不會觸發(fā)系統(tǒng)UI可見性的監(jiān)聽器,因為暫時顯示的導(dǎo)航欄并不被認(rèn)為是一種可見性狀態(tài)的變化。

Noteimmersive類的標(biāo)簽只有在與SYSTEM_UI_FLAG_HIDE_NAVIGATION,SYSTEM_UI_FLAG_FULLSCREEN中一個或兩個一起使用的時候才會生效。你可以只使用其中的一個,但是一般情況下你需要同時隱藏狀態(tài)欄和導(dǎo)航欄以達到沉浸的效果。

選擇一種沉浸方式

SYSTEM_UI_FLAG_IMMERSIVESYSTEM_UI_FLAG_IMMERSIVE_STICKY都提供了沉浸式的體驗,但是在上面的描述中,他們是不一樣的,下面講解一下什么時候該用哪一種標(biāo)簽。

  • 如果你在寫一款圖書瀏覽器、新聞雜志閱讀器,請將IMMERSIVE標(biāo)簽與SYSTEM_UI_FLAG_FULLSCREEN,SYSTEM_UI_FLAG_HIDE_NAVIGATION一起使用。因為用戶可能會經(jīng)常訪問Action Bar和一些UI控件,又不希望在翻頁的時候有其他的東西進行干擾。IMMERSIVE在該種情況下就是個很好的選擇。
  • 如果你在打造一款真正的沉浸式應(yīng)用,而且你希望屏幕邊緣的區(qū)域也可以與用戶進行交互,并且用戶也不會經(jīng)常訪問系統(tǒng)UI。這個時候就要將IMMERSIVE_STICKYSYSTEM_UI_FLAG_FULLSCREENSYSTEM_UI_FLAG_HIDE_NAVIGATION兩個標(biāo)簽一起使用。比如做一款游戲或者繪圖應(yīng)用就很合適。
  • 如果你在打造一款視頻播放器,并且需要少量的用戶交互操作。你可能就需要之前版本的一些方法了(從Android 4.0開始)。對于這種應(yīng)用,簡單的使用SYSTEM_UI_FLAG_FULLSCREENSYSTEM_UI_FLAG_HIDE_NAVIGATION就足夠了,不需要使用immersive標(biāo)簽。

使用非粘性沉浸模式

當(dāng)你使用SYSTEM_UI_FLAG_IMMERSIVE標(biāo)簽的時候,它是基于其他設(shè)置過的標(biāo)簽(SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN)來隱藏系統(tǒng)欄的。當(dāng)用戶向內(nèi)滑動,系統(tǒng)欄重新顯示并保持可見。

用其他的UI標(biāo)簽(如SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATIONSYSTEM_UI_FLAG_LAYOUT_STABLE)來防止系統(tǒng)欄隱藏時內(nèi)容區(qū)域大小發(fā)生變化是一種很不錯的方法。你也需要確保Action Bar和其他系統(tǒng)UI控件同時進行隱藏。下面這段代碼展示了如何在不改變內(nèi)容區(qū)域大小的情況下,隱藏與顯示狀態(tài)欄和導(dǎo)航欄。

// This snippet hides the system bars.
private void hideSystemUI() {
    // Set the IMMERSIVE flag.
    // Set the content to appear under the system bars so that the content
    // doesn't resize when the system bars hide and show.
    mDecorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
            | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
            | View.SYSTEM_UI_FLAG_IMMERSIVE);
}

// This snippet shows the system bars. It does this by removing all the flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
    mDecorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

你可能同時也希望在如下的幾種情況下使用IMMERSIVE標(biāo)簽來提供更好的用戶體驗:

  • 注冊一個監(jiān)聽器來監(jiān)聽系統(tǒng)UI的變化。
  • 實現(xiàn)onWindowFocusChanged()函數(shù)。如果窗口獲取了焦點,你可能需要對系統(tǒng)欄進行隱藏。如果窗口失去了焦點,比如說彈出了一個對話框或菜單,你可能需要取消那些將要在Handler.postDelayed()或其他地方的隱藏操作。
  • 實現(xiàn)一個GestureDetector,它監(jiān)聽了onSingleTapUp(MotionEvent)事件。可以使用戶點擊內(nèi)容區(qū)域來切換系統(tǒng)欄的顯示狀態(tài)。單純的點擊監(jiān)聽可能不是最好的解決方案,因為當(dāng)用戶在屏幕上拖動手指的時候(假設(shè)點擊的內(nèi)容占據(jù)了整個屏幕),這個事件也會被觸發(fā)。

更多關(guān)于此話題的討論,可以觀看這個視頻 DevBytes: Android 4.4 Immersive Mode

使用粘性沉浸模式

當(dāng)使用了SYSTEM_UI_FLAG_IMMERSIVE_STICKY標(biāo)簽的時候,向內(nèi)滑動的操作會讓系統(tǒng)欄臨時顯示,并處于半透明的狀態(tài)。此時沒有標(biāo)簽會被清除,系統(tǒng)UI可見性監(jiān)聽器也不會被觸發(fā)。如果用戶沒有進行操作,系統(tǒng)欄會在一段時間內(nèi)自動隱藏。

圖2展示了當(dāng)使用IMMERSIVE_STICKY標(biāo)簽時,半透明的系統(tǒng)欄展示與又隱藏的狀態(tài)。

imm-sticky

圖2. 自動隱藏系統(tǒng)欄.

下面是一段實現(xiàn)代碼。一旦窗口獲取了焦點,只要簡單的設(shè)置IMMERSIVE_STICKY與上面討論過的其他標(biāo)簽即可。

@Override
public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
}

Notes:如果你想實現(xiàn)IMMERSIVE_STICKY的自動隱藏效果,同時也需要展示你自己的UI控件。你只需要使用IMMERSIVEHandler.postDelayed()或其他類似的東西,讓它幾秒后重新進入沉浸模式即可。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號