巧用PopupMenu實(shí)現(xiàn)NavigationView的二級子菜單

個(gè)人原創(chuàng),轉(zhuǎn)載請注明出處:http://www.reibang.com/p/1dcb9eff6052

來簡書的第一篇文章炸裆,想了想就以這個(gè)作為開頭了^^

概述

寫自己的app時(shí)屿讽,發(fā)現(xiàn)NavigationView的默認(rèn)菜單功能不支持類似OptionMenu那樣點(diǎn)擊后彈出二級子菜單的功能粘衬,思考了下想用PopupMenu來實(shí)現(xiàn)青抛,現(xiàn)將遇到的坑和具體實(shí)現(xiàn)記錄如下科盛。

PopupMenu基本用法

這里推薦使用support-v7包下的PopupMenu兄世,兼容更多版本且功能更豐富:

PopupMenu popupMenu = new PopupMenu(context, anchorView);
popupMenu.inflate(R.menu.xxx);
popupMenu.show();
popupMenu.setOnMenuItemClickListener(...)甜孤;

NavigationView下彈出PopupMenu

上面構(gòu)造函數(shù)的第二個(gè)參數(shù)anchorView表示popupMenu彈出時(shí)確定其位置的錨點(diǎn)老速。于是自然想到用NavigationView的menuitem來實(shí)現(xiàn):

Menu navMenu = navigationView.getMenu();
MenuItem menuItem = navMenu.findItem(R.id.xxx);
anchorView = menuItem.getActionView();

完事了粥喜?還早著呢!編譯后發(fā)現(xiàn)報(bào)錯(cuò):

IllegalStateException: MenuPopupHelper cannot be used without an anchor

提示沒有錨點(diǎn)橘券。咦额湘?我們不是傳入了menuItem.getActionView()作為錨點(diǎn)么?
查詢MenuItem的getActionView()方法源碼后發(fā)現(xiàn)該方法返回的不是一個(gè)具體的控件或布局的view旁舰,所以導(dǎo)致popupMenu無法確定具體的錨點(diǎn)锋华。
在網(wǎng)上搜索了一下解決方法,發(fā)現(xiàn)可以通過給NavigationView的menuItem傳入一個(gè)具體的布局來實(shí)現(xiàn)錨點(diǎn)的定位箭窜,menu.xml代碼如下:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    ...
        <item
            android:id="@+id/nav_xxx"
            android:icon="@drawable/nav_xxx"
            android:title="@string/donate"
            app:actionLayout="@layout/anchor"/> <!--插入的具體布局-->
    ...
</menu>

注意命名空間毯焕,anchor.xml代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="1dp" />

可見只是一個(gè)空的LinearLayout,僅用來定位磺樱。這里將height設(shè)為1主要是為了防止layout擠占menu的空間導(dǎo)致UI變形纳猫。完成后再編譯運(yùn)行婆咸,效果如下:


popupmenu1.gif

功能正常實(shí)現(xiàn)了^^

進(jìn)階:給PopupMenu加上icon

最早的PopupMenu也是可以像NavigationView里的menu一樣給設(shè)置icon的,但后來google為了明確區(qū)分PopupMenu和PopupWindow的使用芜辕,將相應(yīng)的方法給精簡掉了尚骄。但別忘了我們使用的是support-v7包的PopupMenu,這里依然可以利用MenuPopupHelper來實(shí)現(xiàn)物遇。

MenuPopupHelper popupHelper = new MenuPopupHelper(context,(MenuBuilder) menu,view);
popupHelper.setForceShowIcon(true);

其中第二個(gè)參數(shù)需要傳入當(dāng)前menu并轉(zhuǎn)化為MenuBuilder類型乖仇,而PopupMenu類型本身不能轉(zhuǎn)化憾儒,可用popupMenu.getMenu()來實(shí)現(xiàn)询兴。第三個(gè)參數(shù)就是上文已經(jīng)說過的錨點(diǎn)。然后調(diào)用popupHelper的setForceShowIcon(true)方法就可以強(qiáng)制item顯示icon了起趾。
這里還有兩個(gè)小坑:
Android Studio 3.0以上版本調(diào)用MenuPopupHelper的以上兩行代碼時(shí)編譯器會報(bào)“xxx can only be called from within the same library group...”诗舰。這應(yīng)該是個(gè)bug,解決方法很簡單训裆,在調(diào)用以上兩個(gè)方法的方法體前面加上@SuppressLint("RestrictedApi")的注釋眶根,如:

@SuppressLint("RestrictedApi")
private void showPopupMenu(){
            ...
}

填完上面的坑后,運(yùn)行边琉,發(fā)現(xiàn)還是不能顯示icon属百?這是因?yàn)槲覀儗opupMenu的自定義是在popupHelper里進(jìn)行的,所以最后不能用popupMenu.show()变姨,而是要調(diào)用

popupHelper.show();

好了大功告成族扰,看看最終效果吧:


popupmenu2.gif

參考

https://stackoverflow.com/questions/41238545/anchoring-a-popupmenu-to-navigationview-menu-items
https://stackoverflow.com/questions/15454995/popupmenu-with-icons#
https://stackoverflow.com/questions/41150995/appcompatactivity-oncreate-can-only-be-called-from-within-the-same-library-group

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市定欧,隨后出現(xiàn)的幾起案子渔呵,更是在濱河造成了極大的恐慌,老刑警劉巖砍鸠,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扩氢,死亡現(xiàn)場離奇詭異,居然都是意外死亡爷辱,警方通過查閱死者的電腦和手機(jī)录豺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來饭弓,“玉大人双饥,你說我怎么就攤上這事∈酒簦” “怎么了兢哭?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長夫嗓。 經(jīng)常有香客問我迟螺,道長冲秽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任矩父,我火速辦了婚禮锉桑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窍株。我一直安慰自己民轴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布球订。 她就那樣靜靜地躺著后裸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冒滩。 梳的紋絲不亂的頭發(fā)上微驶,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機(jī)與錄音开睡,去河邊找鬼因苹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛篇恒,可吹牛的內(nèi)容都是我干的扶檐。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼胁艰,長吁一口氣:“原來是場噩夢啊……” “哼款筑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蝗茁,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤醋虏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后哮翘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颈嚼,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年饭寺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阻课。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡艰匙,死狀恐怖限煞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情员凝,我是刑警寧澤署驻,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響旺上,放射性物質(zhì)發(fā)生泄漏瓶蚂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一宣吱、第九天 我趴在偏房一處隱蔽的房頂上張望窃这。 院中可真熱鬧,春花似錦征候、人聲如沸杭攻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兆解。三九已至,卻和暖如春卒煞,著一層夾襖步出監(jiān)牢的瞬間痪宰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工畔裕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乖订。 一個(gè)月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓扮饶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親乍构。 傳聞我的和親對象是個(gè)殘疾皇子甜无,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

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