android 系統隱藏和顯示虛擬按鍵的幾種方法(不要太詳細了)

幾種動態顯示虛擬按鍵的方法

上一篇從源碼來看了虛擬按鍵的加載顯示流程
android 虛擬按鍵流程分析
,今天來看看虛擬的幾種動態顯示和隱藏的方法。

其實說到虛擬按鍵,對於市面上面的很多手機,各種需求都不一樣,有的手機有虛擬按鍵,有的手機沒有。今天我就來就各種需要隱藏顯示虛擬按鍵的需求來說說。

1. 我的手機默認是帶虛擬按鍵的,我是一個開發app的人員,我的app的某個activity需要全屏顯示,即需要隱藏掉虛擬按鍵。
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE;
window.getDecorView().setSystemUiVisibility(uiOptions); // 使用activity的window是隱藏虛擬按鍵。
getWindow().setNavigationBarColor(Color.parseColor("#1bb5d7")); //設置虛擬按鍵的背景顏色

這裏已經可以隱藏掉虛擬按鍵了,如果還需要其他需求,可以選擇性的加入以下:

        window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
        window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
        window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
        window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
2. 我是系統開發的,整個系統完全不需要顯示虛擬按鍵,應該如何屏蔽掉虛擬按鍵

看過我上一篇的文章的android 虛擬按鍵流程分析,應該可以發現虛擬按鍵有一個開關

frameworks\base\core\res\res\values\config.xml

    <!-- Whether a software navigation bar should be shown. NOTE: in the future this may be
         autodetected from the Configuration. -->
    <bool name="config_showNavigationBar">false</bool>

​ 可以將以上設置爲false,不過這裏需要注意的是,一般的話這種config 文件都會有overlay文件,所以,請改對應的device下的overlay文件。

​ 另外,上篇文章中也說到了另外一個開關,即谷歌預留的開關,一般的話,系統默認是不會使用的,如果上面改動了,不生效,那就需要看看是不是系統使用了這個 qemu.hw.mainkeys 來控制虛擬按鍵的顯示。

​ 這個prop也給我們提供了一個思路,如果我們需要在代碼中隱藏掉虛擬按鍵,則可以使用這個prop,因爲phoneWindowManager中這個prop比讀取config_showNavigationBar 要晚一點生效。

不過值得注意的是,這個prop設置了之後,似乎系統只有重啓了纔會生效。

3. 我是系統開發的,我需要動態的在某些第三方app中顯示虛擬按鍵,而在另外一些第三方app中不需要顯示虛擬按鍵。

說到這個,我們不得不說一個命令:

adb shell settings put global policy_control <key-values>

即也就是settings 命令,裏面的 policy_control 屬性,它可以實時動態的去選擇隱藏或者顯示虛擬按鍵或者狀態欄,並且可以選擇默認在哪些應用下隱藏,哪些應用下顯示。其實這玩意一看單詞就清楚了,這不就是我們常說的沉浸式嗎?哇哈哈哈

key 含義
immersive.full 同時隱藏
immersive.status 隱藏狀態欄
immersive.navigation 隱藏導航欄

這些鍵對應的值可則如下值用逗號組合:

value 含義
apps 所有應用
* 所有界面
packagename 指定應用
-packagename 排除指定應用

例如:

adb shell settings put global policy_control immersive.full=*

表示設置在所有界面下都同時隱藏狀態欄和導航欄。

adb shell settings put global policy_control immersive.status=com.package1,com.package2:immersive.navigation=apps,-com.package3

表示設置在包名爲 com.package1com.package2 的應用裏隱藏狀態欄,在除了包名爲 com.package3 的所有應用裏隱藏導航欄。

這裏說的都是在adb 裏面或者串口裏面去調試隱藏。但是如果需要在代碼中呢? 那就需要使用

   Settings.Global.putString(context.getContentResolver(), "policy_control", "immersive.navigation=com.package1");

使用這個一定要定要一套規則,否則後面會亂的

4.這裏在補充一下,一般我們會在手機中看到,虛擬按鍵會在某些情況下會過幾秒就消失,然後從屏幕下方劃出則又會出現。這個具體的實現是在:
frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java
 // monitor for system gestures
        mSystemGestures = new SystemGesturesPointerEventListener(context,
                new SystemGesturesPointerEventListener.Callbacks() {
                    @Override
                    public void onSwipeFromTop() {
                        if (mStatusBar != null) {
                           requestTransientBars(mStatusBar);
                        }
                    }
                    @Override
                    public void onSwipeFromBottom() {
                        if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
                                  requestTransientBars(mNavigationBar);
                        }
                    }
                    @Override
                    public void onSwipeFromRight() {
                        if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) {
                            requestTransientBars(mNavigationBar);
                        }
                    }
                    @Override
                    public void onSwipeFromLeft() {
                        if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) {
                            requestTransientBars(mNavigationBar);
                        }
                    }

android 系統的全局手勢滑動是在phoneWindowManager 中的。即從低下往上滑動時走onSwipeFromBottom(),然後再調用requestTransientBars(mNavigationBar) 來顯示虛擬按鍵的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章