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

Android M已經(jīng)發(fā)布了很久了捏境,很多新的特性也非常的吸引人,比如Doze模式可以使導(dǎo)航時(shí)間更長(zhǎng)嘀略,刷到nexus5上蕊玷,體驗(yàn)了一下確實(shí)不錯(cuò)。但是導(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ù)雜萝映,本文的操作步驟如下:

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

文章A的整體思路是在導(dǎo)航欄上添加了一個(gè)圖標(biāo)按鈕,點(diǎn)擊后隱藏導(dǎo)航欄锌俱,上滑顯示導(dǎo)航欄晤郑。首先說一下隱藏導(dǎo)航欄,感覺官方的導(dǎo)航欄還是很完美的贸宏,所以不打算添加任何元素造寝,這里對(duì)任務(wù)鍵(虛擬正方形按鍵)進(jìn)行長(zhǎng)點(diǎn)擊操作進(jìn)行修改;之后通過上滑來顯示導(dǎo)航欄吭练,文章A的思路是通過各種系統(tǒng)內(nèi)的很多回調(diào)與消息的傳遞完成的诫龙,改動(dòng)幅度蠻大的,自己嘗試按照文章中的進(jìn)行修改鲫咽,需要對(duì)文章A中提到的部分進(jìn)行修改外签赃,還需對(duì)部分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ū)動(dòng)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ī)時(shí)僅僅刷進(jìn)system.img即可马绝,首次刷機(jī)盡量把userdata.img, boot.img都進(jìn)行刷入

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

虛擬按鍵有3個(gè)挣菲,考慮到返回鍵一般有一定的作用富稻,于是修改任務(wù)鍵(虛擬正方形按鍵)的長(zhǎng)點(diǎn)擊事件,使其在長(zhǎng)點(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);
    //去除長(zhǎng)點(diǎn)擊操作
    //mNavigationBarView.getRecentsButton().setOnLongClickListener(mLongPressBackRecentsListener);
    mNavigationBarView.getBackButton().setLongClickable(true);
    mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener);
    mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
    mNavigationBarView.getHomeButton().setOnLongClickListener(mLongPressHomeListener);
    //添加長(zhǎng)點(diǎn)擊操作唉窃,長(zhǎng)點(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();
}

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

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

上滑顯示導(dǎo)航欄借鑒了文章A中的一些技巧,在系統(tǒng)上滑時(shí)會(huì)回調(diào)./frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java的修改主要是實(shí)現(xiàn)onSwipeFromBottom(豎屏?xí)r)和onSwipeFromRight(橫屏?xí)r)兩個(gè)接口苟跪,在此兩接口內(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中對(duì)廣播進(jìn)行處理,將狀態(tài)欄添加到windowManager中件已。

 @Override
public void start() {
//省略代碼笋额,在此方法末尾動(dòng)態(tài)注冊(cè)廣播監(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;

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

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

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

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

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

      source build/envsetup.sh  //初始化環(huán)境變量
      lunch //切換編譯平臺(tái)
    
  • ②編譯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
    

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

效果

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


Paste_Image.png
Paste_Image.png

后記

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

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末徙鱼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子惰聂,更是在濱河造成了極大的恐慌疆偿,老刑警劉巖咱筛,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異杆故,居然都是意外死亡迅箩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門处铛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來饲趋,“玉大人,你說我怎么就攤上這事撤蟆∞人埽” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵家肯,是天一觀的道長(zhǎng)龄砰。 經(jīng)常有香客問我,道長(zhǎng)讨衣,這世上最難降的妖魔是什么换棚? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮反镇,結(jié)果婚禮上固蚤,老公的妹妹穿的比我還像新娘。我一直安慰自己歹茶,他們只是感情好夕玩,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惊豺,像睡著了一般燎孟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上扮叨,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天缤弦,我揣著相機(jī)與錄音,去河邊找鬼彻磁。 笑死碍沐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的衷蜓。 我是一名探鬼主播累提,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼磁浇!你這毒婦竟也來了斋陪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎无虚,沒想到半個(gè)月后缔赠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡友题,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年嗤堰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片度宦。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡踢匣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出戈抄,到底是詐尸還是另有隱情离唬,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布划鸽,位于F島的核電站输莺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏漾稀。R本人自食惡果不足惜模闲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望崭捍。 院中可真熱鬧,春花似錦啰脚、人聲如沸殷蛇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽粒梦。三九已至,卻和暖如春荸实,著一層夾襖步出監(jiān)牢的瞬間匀们,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工准给, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泄朴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓露氮,卻偏偏與公主長(zhǎng)得像祖灰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子畔规,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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