Android導(dǎo)航欄隱藏與浮現(xiàn)(一)

Android M已經(jīng)發(fā)布了很久了,很多新的特性也非常的吸引人,比如Doze模式可以使導(dǎo)航時間更長,刷到nexus5上,體驗(yàn)了一下確實(shí)不錯。但是導(dǎo)航欄(虛擬按鍵)一直存在,感覺不是特別的爽。今天我們就從android M(6.0)進(jìn)行源碼的修改,使nexus5能夠方便的進(jìn)行導(dǎo)航欄的隱藏與恢復(fù)。

修改源碼前,看到了CSDN上的文章(http://blog.csdn.net/way_ping_li/article/details/45727335,記為文章A),寫的很好,但是寫的有些省略,整體的操作也較為復(fù)雜,本文的操作步驟如下:

① 下載并編譯源碼
② 長點(diǎn)擊隱藏導(dǎo)航欄
③ 上滑顯示導(dǎo)航欄
④ 編譯部分修改代碼,重新生成system.img

文章A的整體思路是在導(dǎo)航欄上添加了一個圖標(biāo)按鈕,點(diǎn)擊后隱藏導(dǎo)航欄,上滑顯示導(dǎo)航欄。首先說一下隱藏導(dǎo)航欄,感覺官方的導(dǎo)航欄還是很完美的,所以不打算添加任何元素,這里對任務(wù)鍵(虛擬正方形按鍵)進(jìn)行長點(diǎn)擊操作進(jìn)行修改;之后通過上滑來顯示導(dǎo)航欄,文章A的思路是通過各種系統(tǒng)內(nèi)的很多回調(diào)與消息的傳遞完成的,改動幅度蠻大的,自己嘗試按照文章中的進(jìn)行修改,需要對文章A中提到的部分進(jìn)行修改外,還需對部分aidl以及與此相關(guān)的類進(jìn)行修改等,比較的繁瑣,當(dāng)然最后實(shí)現(xiàn)了上滑顯示,本文將通過廣播來進(jìn)行上滑操作的傳遞。

下載并編譯源碼

源碼的下載編譯可以參考google官方教程https://source.android.com/source/downloading.html,本文編譯的源碼分支android-6.0.1_r50。

nexus5源碼下載后需要下載驅(qū)動https://developers.google.com/android/nexus/drivers,解壓到根目錄后執(zhí)行,執(zhí)行后產(chǎn)生vendor目錄,之后編譯代碼

源碼編譯完成后,之后的framework的修改不用再次重新編譯,只需使用mmm命令編譯部分模塊即可,最后使用make snod生成system.img,刷進(jìn)手機(jī)即可。

修改framework后生成的system.img,在進(jìn)行刷機(jī)時僅僅刷進(jìn)system.img即可,首次刷機(jī)盡量把userdata.img, boot.img都進(jìn)行刷入

長點(diǎn)擊隱藏導(dǎo)航欄

虛擬按鍵有3個,考慮到返回鍵一般有一定的作用,于是修改任務(wù)鍵(虛擬正方形按鍵)的長點(diǎn)擊事件,使其在長點(diǎn)擊后可以隱藏導(dǎo)航欄。

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

private void prepareNavigationBarView() {
    mNavigationBarView.reorient();

    mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
    mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
    mNavigationBarView.getRecentsButton().setLongClickable(true);
    //去除長點(diǎn)擊操作
    //mNavigationBarView.getRecentsButton().setOnLongClickListener(mLongPressBackRecentsListener);
    mNavigationBarView.getBackButton().setLongClickable(true);
    mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener);
    mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
    mNavigationBarView.getHomeButton().setOnLongClickListener(mLongPressHomeListener);
    //添加長點(diǎn)擊操作,長點(diǎn)擊進(jìn)行導(dǎo)航欄的刪除
    mNavigationBarView.getRecentsButton().setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {
            mWindowManager.removeView(mNavigationBarView);
            mNavigationBarView = null ;
            //isNavigationShow用于記錄當(dāng)前導(dǎo)航欄狀態(tài),定義在PhoneStatusBar的全局變量中
            isNavigationShow = false ;
            Log.d("===>LYD", "remove navigation bar");

            return true;
        }
    });
    mAssistManager.onConfigurationChanged();
}

此時進(jìn)行長點(diǎn)擊任務(wù)鍵將隱藏導(dǎo)航欄。

上滑顯示導(dǎo)航欄

上滑顯示導(dǎo)航欄借鑒了文章A中的一些技巧,在系統(tǒng)上滑時會回調(diào)./frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java的修改主要是實(shí)現(xiàn)onSwipeFromBottom(豎屏?xí)r)和onSwipeFromRight(橫屏?xí)r)兩個接口,在此兩接口內(nèi)發(fā)送廣播。

./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 && mNavigationBarOnBottom) {
                        requestTransientBars(mNavigationBar);
                    }    
                    //開始發(fā)送廣播
                    Intent intent = new Intent();
                    intent.setAction("LYD_SHOW_NAVIGATION_BAR");
                    mContext.sendBroadcast(intent);
                }    
                @Override
                public void onSwipeFromRight() {
                    if (mNavigationBar != null && !mNavigationBarOnBottom) {
                        requestTransientBars(mNavigationBar);
                    }    
                    //開始發(fā)送廣播
                    Intent intent = new Intent();
                    intent.setAction("LYD_SHOW_NAVIGATION_BAR");
                    mContext.sendBroadcast(intent);
                }    
                //省略后續(xù)代碼

下面我們需要做的是在之前的PhoneStatusBar中對廣播進(jìn)行處理,將狀態(tài)欄添加到windowManager中。

 @Override
public void start() {
//省略代碼,在此方法末尾動態(tài)注冊廣播監(jiān)聽器

    IntentFilter filter = new IntentFilter();
    filter.addAction("LYD_SHOW_NAVIGATION_BAR");
    mContext.registerReceiver(navBarBroadcastReceiver, filter);
}

private BroadcastReceiver navBarBroadcastReceiver = new LydShowNavigationBarBroadcast();

private static boolean isNavigationShow = true ;

//自定義廣播
class LydShowNavigationBarBroadcast extends  BroadcastReceiver{
    public LydShowNavigationBarBroadcast() {
        super();
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("====>LYD", "receiver show navigation bar broadcast");

        //防止多次被添加
        if(isNavigationShow){
            return ;
        }

        showNavigationBar();
    }

    @Override
    public IBinder peekService(Context myContext, Intent service) {
        return super.peekService(myContext, service);
    }
}  

//展示導(dǎo)航欄
public void showNavigationBar() {
    mNavigationBarView =(NavigationBarView) View.inflate(mContext, R.layout.navigation_bar, null);
    mNavigationBarView.setBar(this);
    prepareNavigationBarView();
    addNavigationBar();
    isNavigationShow = true;

    //防止在桌面時上拉出導(dǎo)航欄時,導(dǎo)航欄背景為黑色
    mNavigationBarView.setBackgroundColor(Color.TRANSPARENT);
    Log.d("===>LYD", "show navigation");
}

注意導(dǎo)入android.graphics.Color類

代碼到此就修改完了,下面我們只需要對相應(yīng)模塊進(jìn)行編譯就行了。

編譯部分修改代碼,重新生成system.img

  • ①切換到源代碼目錄,運(yùn)行

      source build/envsetup.sh  //初始化環(huán)境變量
      lunch //切換編譯平臺
    
  • ②編譯PhoneWindowManager.java所在模塊(core)

      mmm ./frameworks/base/services/core/
      mmm ./frameworks/base/services/
    
  • ③編譯PhoneStatusBar.java所在模塊(SystemUI)

      mmm ./frameworks/base/packages/SystemUI/
    
  • ④生成system.img.

       make snod
    
  • ⑤刷入system.img

      adb reboot bootloader
      fastboot flash system system.img
    

這樣一個定制過導(dǎo)航欄的nexus5(hammerhead)系統(tǒng)已經(jīng)制作完成了。

效果

解決了導(dǎo)航欄的隱藏與浮現(xiàn),終于可以不用一直看著不搭配的導(dǎo)航欄了。下面是隱藏前后QQ音樂的截圖:


Paste_Image.png
Paste_Image.png

后記

能夠給該功能在設(shè)置中加一個開關(guān)就完美了,快來查看Android導(dǎo)航欄隱藏與浮現(xiàn)(二)吧。

由于筆者一般都是使用手機(jī)都是豎屏的,為了減少誤操作,所以僅僅上滑時(swipeFromBottom)才顯示導(dǎo)航欄,從右側(cè)滑動(swipeFromRight)不觸發(fā)操作。

刷機(jī)有風(fēng)險,大家需謹(jǐn)慎,本文僅僅是提供一種思想,刷機(jī)造成的問題與本文以及作者無關(guān)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,908評論 2 372

推薦閱讀更多精彩內(nèi)容