天天看點

[官翻] 隐藏狀态欄

官網原文:https://developer.android.com/training/system-ui/status.html

隐藏狀态欄

這個課程将描述如何在不同版本的上隐藏狀态欄。隐藏狀态欄(可選:導航欄)可以讓你的内容有更多的空間可以顯示,進而為使用者提供一個更有沉浸式的體驗。

圖1展示了一個可見的狀态欄的程式界面:

[官翻] 隐藏狀态欄

圖1:狀态欄可見

圖2展示了一個不可見的狀态欄的程式界面,注意:這個action bar也被隐藏了,你永遠也不要在狀态欄隐藏的情況下顯示action bar。

[官翻] 隐藏狀态欄

圖2:狀态欄不可見

在android4.0或以下版本中隐藏狀态欄

你可以在android4.0(API 14)或者以下的版本中通過 

WindowManager标記來設定,你可以通過代碼中來設定或者在你的manifest檔案中對某個activity設定主題來達到目的。如果你的狀态欄會一直被隐藏掉的話,在你的manifest檔案中對某個activity設定主題是首選的方式(嚴格來說:是覆寫主題中的那個屬性),比如:

<application
    ...
    android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" >
    ...
</application>      

使用theme主題的方式有如下幾個優點:

1、便于維護且相對于在代碼中用WindowManager的标記來說更不容易出錯

2、效果會更平滑,因為在執行個體化(渲染)activity的之前就已經被系統處理了。(此處翻譯得不太好,大體意思到了吧)

當然,你還是可以選擇用WindowManager的标記來做,如下方法可以簡單的在你的代碼中來控制狀态欄的隐藏與顯示:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // If the Android version is lower than Jellybean, use this call to hide
        // the status bar.
        if (Build.VERSION.SDK_INT < 16) {
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }
        setContentView(R.layout.activity_main);
    }
    ...
}      

當你設定WindowManager标記的時候(不管是代碼中設定還是theme中設定),除非你手動清除掉這個标記,這個狀态(指的是狀态欄隐藏或者顯示的狀态)将會一直不變。

當你啟用了FLAG_FULLSCREEN标記,你可以用FLAG_LAYOUT_IN_SCREEN 來設定你的activity的布局與螢幕的可用空間(大小或尺寸)相同,它可以在你隐藏或顯示狀态欄的時候使内容區域保持不變。

在android4.1或以上版本中隐藏狀态欄

你可以在android4.1(API level 16)以上中設定 

setSystemUiVisibility()來隐藏狀态欄。setSystemUiVisibility()是在單獨的view層級上設定UI标記;這些設定是聚合在window層級的。使用setSystemUiVisibility()來設定UI标記可以讓你相對于使用 

WindowManager标記來說具有更大的操作性。如下是隐藏狀态欄的一個小片段:

View decorView = getWindow().getDecorView();
// 隐藏狀态欄
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
// 如上所說,你永遠也不要在狀态欄隐藏的情況下顯示action bar。是以這裡的隐藏就是有必要的。
ActionBar actionBar = getActionBar();
actionBar.hide();      

注意以下幾點:

1、一旦UI标記被清除(比如:通過導航欄離開/關閉了這個activity),如果你還想隐藏狀态欄的話,你的app需要重新設定它們。你可以通過這個連結Responding to UI Visibility Changes 來讨論如何監聽UI是否可見且作出相應操作。

2、在你設定UI标記的那個地方就開始起作用了(譯者注:也就是說在代碼那一行運作後就會讓狀态欄立刻隐藏或顯示)。如果你是在activity的onCreate()的方法中隐藏的系統欄(導航欄和狀态欄),那麼當使用者按下Home鍵,系統欄将重新出現。當使用者重新打開activity,onCreate()不會被調用,是以系統欄将會出現。如果你想不受進或出activity的影響,把UI标記設定在

onResume()

 或者onWindowFocusChanged()裡吧!

3、隻如果你調用的這個view是可見的,

setSystemUiVisibility()

 這個方法隻會起效一次。

4、從這個視圖導航(跳轉)走了的話,這個view的setSystemUiVisibility()标記将被清除掉。

讓内容在狀态欄後面顯示

在android4.1或者以上版本,你可以設定應用的内容在狀态欄後面顯示,是以它就不受狀态欄的隐藏與顯示的影響而重新調整大小。這麼幹:用SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN标記吧!你也可以用

SYSTEM_UI_FLAG_LAYOUT_STABLE

 來幫助你的應用維持一個穩定的布局。

當你使用了這個方法,你的應用UI中的關鍵區域(比如:地圖應用中的嵌入式控件)的穩定不被系統欄覆寫就變成你的責任了。這可能讓你的應用不可用(譯者注:我也沒搞懂這一句)。在大多數情況下,你可以通過在你的XML布局檔案中添加android:fitsSystemWindows這個屬性來解決(設定這個屬性為true),它會根據系統視窗來設定你的父容器的padding,這個方法對絕大多數的應用來說是可行的。

在某些情況下,不管怎樣,你可能需要修改預設的padding值來達到你的目的。通過重寫fitSystemWindows(Rect insets)去直接操縱與系統欄的布置關系(像内容插入到系統的視窗一樣去占據一個已知大小空間)。當插入到系統視窗的内容改變後,fitSystemWindows()這個方法是被view層級調用的,想要允許系統視窗根據内容來調整可以通過重寫這個方法處理任何你想要的插入。