国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

沉浸式模式

2019-11-06 09:42:36
字體:
來源:轉載
供稿:網友

第一次在項目中要用到全屏功能的時候無從下手,然后就是去百度了。百度到的結果都是差不多的。不過直接把代碼貼過來的確是可以用的。但是除了知道怎么做之外還想去理解它,因為只有理解了才能舉一反三嘛。好在在后來的時候看到了官方的文檔,寫的非常詳細。

–> 我是官方文檔 <–

接下來開始正題

… … …

先給出一些名詞方便下面的講解

StatusBar StatusBar

NavigationBar NavigationBar

SystemBar – StatusBar 跟 NavigationBar 的統稱


設置全屏主要分為兩種方式:

4.0 之前采用的方式4.0 之后新增的方式

4.0 以及之前設置全屏

因為 4.0 之前的系統已經很少了,所以這里就簡單的說一下。 有兩種方式可以實現全屏:

使用全屏的主題getWindow().addFlag(WindowManager.LayoutParams.FLAG_FULLSCREEN);

這種全屏方式是無法隱藏 NavigationBar 的(如果有 NavigationBar 的話),因為 NavigationBar 是在 4.0 以后才引入的。使用這種方式設置全屏的特點是,離開了 App 后再進入 App 時,依然處于全屏模式,只能清除掉全屏標志位才能退出全屏。


4.1 以及之后設置全屏

4.1 以及之后使用 View 的 setSystemUiVisibility() 來對 SystemBar 進行控制。 任何 View 都可以用來調用這個方法,只要它是可見狀態的。

下面先把要涉及到的 flag 分組列舉出來(所有的 flag 都是以 SYSTEM_UI_FLAG 作為前綴,所以下面將其省略)。

控制 SystemBar 相關:

FULLSCREENHIDE_NAVIGATIONLOW_PROFILE

布局相關:

LAYOUT_SCREENLAYOUT_HIDE_NAVIGATIONLAYOUT_STABLE

沉浸式相關 (4.4 引入):

IMMERSIVEIMMERSIVE_STICKY

超前提示:

在離開 App 時,比如按了 home / 多任務鍵 會導致設置的控制 SystemBar 相關的 flag 被清除,而其他設置的 flag 不會受到影響。

FULLSCREEN

雖然寫的是 Fullscreen ,但其實只是隱藏 StatusBar。

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    mDecorView = getWindow().getDecorView();    mDecorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);    // Google 建議隱藏 StatusBar 時也將 ActionBar 一起隱藏    getActionBar().hide();}1234567891012345678910

這里寫圖片描述

看圖可以得出以下幾點:

點擊屏幕 StatusBar 不會顯示出來從屏幕上邊緣往下滑可以讓 StatusBar 重新顯示點擊 home / 多任務鍵再返回 App 時 StatusBar 重新顯示了出來,印證了超前提示里所說的。而且 StatusBar 在顯示出來以后不會自動隱藏,這一點跟在 4.1 之前設置的全屏方式不一樣,因為設置的 FULLSCREEN flag 已經被清除了,如果想重新隱藏,需要重新設置該 flag。StatusBar 的顯示 / 隱藏會使 ImageView 大小發生了變化

為了防止布局大小不會因為 StatusBar 的顯示 / 隱藏發生變化,有兩種 flag 可供選擇:

1.LAYOUT_STABLE

mDecorView.setSystemUiVisibility(        View.SYSTEM_UI_FLAG_FULLSCREEN                 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);123123

這里有一點需要注意:設置多個標志位時要用 | 連接起來,不能多次調用 setSystemUiVisibility。如:

mDecorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);mDecorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);1212

這樣的結果就是只有最后一次設置的 flag 生效,而之前設置的標志位會被清除。也就是說上面的代碼中只設置了 LAYOUT_STABLE 而 FULLSCREEN 被清除了。所以如果想清除之前設置的所有 flag ,mDecorView.setSystemUiVisibility(0) 就可以了

這次布局并沒有延伸到 StatusBar 底下,所以大小也就不會受到它的影響

2.LAYOUT_FULLSCREEN

mDecorView.setSystemUiVisibility(        View.SYSTEM_UI_FLAG_FULLSCREEN                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);123123

可以看到布局已經延伸到了 StatusBar 底部。

HIDE_NAVIGATION

protected void onCreate(Bundle savedInstanceState) {    mDecorView.setSystemUiVisibility(        View.SYSTEM_UI_FLAG_FULLSCREEN            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);}1234512345

Google 建議隱藏 NavigationBar 的同時將 StatusBar 一起隱藏。

與隱藏 StatusBar 時不同的是,隱藏了 NavigationBar 以后,點擊屏幕的任何位置都會導致設置的所有控制 SystemBar 相關的 flag 被清除,所以 SystemBar 重新顯示了出來。這里還需要注意的在這種模式下點擊屏幕點擊事件會被屏蔽,要等到 SystemBar 顯示出來以后再次點擊,事件才會傳遞到我們的布局中。

與 LAYOUT_FULLSCREEN 類似的是, LAYOUT_HIDE_NAVIGATION 可以讓布局內容延伸到 NavigationBar 的底部。

因為離開 App 后控制 SystemBar 相關的 flag 會被清除,所以可以按需在 onResume() 或者 onWindowFocusChanged() 中重新設置它們。

LOW_PROFILE

protected void onCreate(Bundle savedInstance) {    mDecorView.setSystemUiVisibility(                View.SYSTEM_UI_FLAG_LOW_PROFILE);}12341234

作用是減少 StatusBar 中的圖標并使其變暗,將 NavigationBar 中的按鈕減弱成 3 個點。 知乎在閱讀文章的時候就使用到了這個模式

這里寫圖片描述

可以看到,在向上滑動內容的時候 SystemBar 的內容被弱化了,這樣可以減少其他元素對閱讀者的干擾。

設置沉浸式模式(4.4 之后引入)

沉浸式模式是在 4.4 之后才引入的


IMMERSIVE

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             | View.SYSTEM_UI_FLAG_FULLSCREEN            | View.SYSTEM_UI_FLAG_IMMERSIVE);12345671234567

可以看到設置了該 flag 以后,點擊屏幕不會讓 SystemBar 顯示出來。呼出 SystemBar 的方式是在屏幕上邊緣向下滑動,在呼出 SystemBar 后,控制 SystemBar 相關的 flag 會被清除。

IMMERSIVE_STICKY

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             | View.SYSTEM_UI_FLAG_FULLSCREEN            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);12345671234567

跟 IMMERSIVE 不同的是,在該模式下呼出的 SystemBar 會在短暫的顯示后重新隱藏。并且在 SystemBar 顯示出來的時候點擊屏幕中心會立刻讓 SystemBar 重新隱藏。所以在模式下呼出 SystemBar 并不會清除控制 SystemBar 相關的 flag。但是離開 App 時控制 SystemBar 相關的 flag 還是會被清除。

所以在回到 App 的時候需要重新設置:

@Overridepublic 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);}}123456789101112123456789101112

監聽 SystemBar 的變化

通常情況下我們需要能夠控制 SystemBar 的顯示與隱藏,這個時候就需要監聽 SystemBar 的狀態。 通過 OnSystemUiVisibilityChangeListener 就可以對 SystemBar 的狀態進行監聽。

protected void onCreate(Bundle savedInstance) {    mDecorView.setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {        @Override        public void onSystemUiVisibilityChange(int visibility) {            if (visibility == 0) {            // SystemBar 處于顯示狀態            } else {            // SystemBar 處于隱藏狀態            }        }});12345678910111234567891011

上面的代碼展示了如何對 SystemBar 的狀態進行監聽。 當 SystemBar 的顯示狀態發生變化時,onSystemUiVisibilityChange() 方法就會被調用。但是有一個例外,設置 IMMERSIVE_STICKY 后將 SystemBar 呼出并不會觸發該監聽器。

下面具體解釋一下 onSystemUiVisibilityChange(int visibility) 方法

onSystemUiVisibilityChange(int visibility) 方法中的 visibility 參數表示的是 LOW_PROFILE、FULLSCREEN 跟HIDE_NAVIGATION 這三個 flag 的值的和。

FULLSCREEN(4)HIDE_NAVIGATION(2)LOW_PROFILE(1)

括號中的數字是它們的值。

為什么 visibility 只是表示這 3 個 flag 的和呢?因為只有這 3 個值是跟控制 SystemBar 相關的。也就是說從visibility 的值就可以只知道我們設置了哪些 flag。比如當 visibility 等于 4 時,說明設置了 FULLSCREEN 這個 flag;如果 visibility 等于 7 則說明 3 種 flag 都設置了。所以當 visibility 為 0 時表示沒有設置任何控制 SystemBar 的 flag,也就說明了 SystemBar 當前處于顯示狀態。

那為什么 visibility 的值會是它們三個的和呢?因為我們在設置 flag 的時候是用 | 將多個 flag 連接在一起的, | 就相當于把它們的值加起來。

下面給出一個 Demo ,功能是點擊圖片時進入 / 退出全屏

public class MainActivity extends AppCompatActivity {    private static final String TAG = "MainActivity";    @BindView(R.id.image)    ImageView mImage;    View mDecorView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ButterKnife.bind(this);        mDecorView = getWindow().getDecorView();        // 讓圖片鋪滿屏幕        mDecorView.setSystemUiVisibility(                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);    }    @OnClick(R.id.image)    public void onClick() {        // 只需要處理隱藏 SystemBar 就行了,因為顯示 SystemBar 是由系統完成的        hideSystemUI();    }    private void hideSystemUI() {        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                        | View.SYSTEM_UI_FLAG_FULLSCREEN);    }    private void showSystemUI() {        mDecorView.setSystemUiVisibility(                View.SYSTEM_UI_FLAG_LAYOUT_STABLE                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);    }}12345678910111213141516171819202122232425262728293031323334353637383940414243441234567891011121314151617181920212223242526272829303132333435363738394041424344

這里有一個問題,如果點擊稍微快一點的話就會出現只隱藏 StatusBar 而沒有隱藏 NavigationBar 的情況。如果有哪個小伙伴知道的話請告知一下。

希望這篇文章能給大家帶來一點點幫助。

頂8
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 巫山县| 博罗县| 台中市| 新余市| 班玛县| 永泰县| 思茅市| 神木县| 曲松县| 湘乡市| 大理市| 广州市| 寿宁县| 巨鹿县| 雅安市| 鲜城| 大理市| 青冈县| 成都市| 晋宁县| 南昌县| 株洲市| 石泉县| 呈贡县| 仁怀市| 贡觉县| 阿瓦提县| 祁连县| 松江区| 航空| 罗甸县| 赤水市| 巴彦县| 济源市| 中超| 志丹县| 扬州市| 仲巴县| 安平县| 安乡县| 石城县|