記錄一下Popmenu的使用以及一些坑:自定義Popupmenu、Menu、Popupmenu添加icon


在這裏插入圖片描述

壹、Popupmenu的基本使用,定義和獲取對應的menu菜單項。

  • 首先我們來定義一個menu.xml來放我們的菜單項目。
	menu xmlns:app="http://schemas.android.com/apk/res-auto"
		xmlns:android="http://schemas.android.com/apk/res/android" >
		<item
			android:id="@+id/changeIO"
			android:orderInCategory="120"
			android:icon="@drawable/changeio"
			android:title="切換進出方向" />
	
		<item
			android:id="@+id/workstart"
			android:orderInCategory="120"
			android:icon="@drawable/work"
			android:title="出工" />
		<item
			android:id="@+id/workfinish"
			android:orderInCategory="120"
			android:icon="@drawable/finishwork"
			android:title="收工" />
		<item
			android:id="@+id/rollcall"
			android:orderInCategory="120"
			android:icon="@drawable/rollcall"
			android:title="點名" />
		<item
			android:id="@+id/areactrl"
			android:orderInCategory="120"
			android:icon="@drawable/areactrl"
			android:title="零星流動" />
	</menu>
  • 然後我們直接把菜單按鈕設置監聽,在裏面定義popupmenu。獲取表單信息即可。下面兩行代碼放進去就行。功能就是點擊圖標按鈕即可彈出菜單。
        private View.OnClickListener ioSwitcherListener = v -> {
        PopupMenu popupMenu = new PopupMenu(FaceActivity.this, v);       //FaceActivity是當前使用類
        popupMenu.getMenuInflater().inflate(R.menu.face_menu, popupMenu.getMenu());
        popupMenu.show();      //關鍵,彈出菜單顯示
        }
  • 我們來看看具體效果圖吧。這是我之前啥效果都沒加的時候。只列了兩個選項。可以看到沒有分割線。白白的很醜。我們後面愛繼續優化吧。
    在這裏插入圖片描述

貳、Popupmenu設置字體風格和彈出定位。添加分割線。

  • 由於風格單調,我們需要把它弄得好看一點。做安卓的應該都做過按鈕。和按鈕這些一樣。我們看可以單獨爲他定製一個style。在value文件夾裏面新建itemstyle.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="mainStyle" parent="Theme.AppCompat">         <!--主風格、mainStyle-->
        <item name="android:dropDownListViewStyle">@style/popmenuDivier</item>
        <item name="android:textAppearanceSmallPopupMenu">@style/popmenuText</item>
        <item name="android:textAppearanceLargePopupMenu">@style/popmenuText</item>
    </style>
    <!--popmenu的字體顏色-->
    <style name="popmenuText">
        <item name="android:textColor">@color/white</item>
        <item name="android:textSize">20sp</item>
        <item name="android:gravity">center</item>
    </style>
    <!--popMenu分割線的顏色-->
    <style name="popmenuDivier">
        <item name="android:divider">@color/md_blue_600</item>
        <item name="android:dividerHeight">2sp</item>
    </style>
</resources>
  • 關於這個style文件,我具體還沒摸清哪些風格對應的是啥。主風格里面嵌套其他風格。引用繼承的關係。主風格parent網上的都是寫的AppThem。我用這個無法編譯。我開始把它刪了。所有都可以用。這個parent其實可有可無。但是後面添加icon就出問題了。所以我才加了Theme.AppCompat。但是加了這個就無法使用popupmenu的背景、定位的自定義風格。目前沒找到問題所在。希望後來的大佬知道的指點一下。因爲我的也可以將就着用。我就沒添加背景和定位!關於定位和背景需要的。大家可以參考一下這篇博客
  • 最後在對應使用的activity配置,例如我的是FaceActivity,把這一條添加到對應的activity就行了。
    在這裏插入圖片描述
  • 我們來看看具體效果圖,添加了分割線,字體風格和Theme.AppCompat默認背景風格。到這一步差不多就是下面的風格。奇怪的是沒有定位它默認跑到一個合理的位置上了,免去了定位的煩惱。
    在這裏插入圖片描述
  • 由於之前我沒有繼承parent。定位和背景也可以正常使用看看你我的先後對比圖。這是沒有設置定位和背景
    在這裏插入圖片描述
  • 這是設置了背景和定位的。這些在主風格都沒繼承parent的。可以看到就整齊美觀了許多。
    在這裏插入圖片描述

叄、爲Popupmenu添加icon:兩種方法:反射、子菜單模式

a、利用反射強制展示icon。這裏面有點坑。

  • 雖然定位,背景都設置了,但是還是覺得很醜。這時候我就嘗試着爲每個表單添加icon。也就是本文開始的那種效果。我搜了許多,都是用的反射顯示。我也用的反射實現的。我們只需要在剛纔定義popupmenu的後面加一段代碼即可實現。
//使用反射,強制顯示菜單圖標
        try {
            Field field = popupMenu.getClass().getDeclaredField("mPopup");
            field.setAccessible(true);
            MenuPopupHelper mHelper = (MenuPopupHelper) field.get(popupMenu);
            mHelper.setForceShowIcon(true);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }finally {
            popupMenu.show();
        }
  • 說到這裏我就有話要說了。由於之前項目比較老了。這個MenuPopupHelper死都不出來。android.support.v7.widget報找不到。檢查發現我導的包和別人用的不一樣。我又嘗試添加了一下依賴。在這裏插入圖片描述
    結果解決了麼,並沒有!又報錯了。編譯失敗,說我v4和v7衝突了。反正就是這個問題。最後檢查發現在另一個build.gradle裏面還有個v4.我把它註釋了就好了。貌似v4和v7差不多。但是有重合的部分。網上說把衝突的jar刪了即可。
    在這裏插入圖片描述

b、子菜單模式,不用反射,直接顯示。

  • 利用表嵌套,當然具體還看需求而定。我還沒嘗試如何怎麼調整顯示爲我想要的效果。但至少提供了一種思路。這是我在谷歌上找到的。百度上的都是利用那個反射強制顯示的。這個就直接第一步的代碼啥都不用加。
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
	xmlns:android="http://schemas.android.com/apk/res/android" >
	<item
		android:id="@+id/main"
		android:orderInCategory="120"
		android:title="主菜單" >
	<menu>
	<item
		android:id="@+id/changeIO"
		android:orderInCategory="120"
		android:icon="@drawable/changeio"
		android:title="切換進出方向" />

	<item
		android:id="@+id/workstart"
		android:orderInCategory="120"
		android:icon="@drawable/work"
		android:title="出工" />
	<item
		android:id="@+id/workfinish"
		android:orderInCategory="120"
		android:icon="@drawable/finishwork"
		android:title="收工" />
	<item
		android:id="@+id/rollcall"
		android:orderInCategory="120"
		android:icon="@drawable/rollcall"
		android:title="點名" />
	<item
		android:id="@+id/open"
		android:orderInCategory="120"
		android:icon="@drawable/areactrl"
		android:title="零星流動" />
	</menu>
	</item>
</menu>

在這裏插入圖片描述

肆、動態管理Popupmenu表單項。隱藏菜單中指定的選項。

  • 這個問題不知道是我沒找到還是啥,各大網站沒找到對應的解決方案。最後在谷歌找到的。一種是比較愚蠢的,添加所需的menu項.可以參照着我的menu.xml看。但是這個蠢就蠢在我費勁千辛萬苦添上去的icon又不在了。變成了這個樣子。
       popupMenu.getMenu().add(Menu.NONE, R.id.rollcall, Menu.NONE, "點名詳情");
       popupMenu.getMenu().add(Menu.NONE, R.id.workfinish, Menu.NONE, "收工");
       popupMenu.getMenu().add(Menu.NONE, R.id.changeIO, Menu.NONE, "切換進出方向");

在這裏插入圖片描述

  • 另外就是比較nice的解決方案了。原理就是把他的顯示參數設置爲不可見。答案來自谷歌。手動笑哭!!我把其中兩個隱藏了。這樣我們就可以根據後端傳過來的標識顯示對應的menu項。最後效果:看着就會很nice !我特麼把這生生搞成了進化史!哈哈
	   popupMenu.getMenu().findItem(R.id.rollcall).setVisible(false);
       popupMenu.getMenu().findItem(R.id.workfinish).setVisible(false);

在這裏插入圖片描述

伍、爲Popupmenu菜單設置監聽。

  • 最難的我們都經歷了,剩下來這個就比較簡單了。直接Switch就行了。哇,寫累了直接上代碼吧!手動滑稽!直接加在popupmenu.show後面就行
        popupMenu.setOnMenuItemClickListener(
            new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    switch (item.getItemId()) {                     
                        case R.id.rollcall:
                            Comm.loger.output("切換點名。");
                            break;
                        case R.id.workstart:
                            Comm.loger.output("切換出工。");
                            break;
                     //此處省略一萬字
                        default:
                            // 隱藏該對話框
                            Toast.makeText(FaceActivity.this,
                                    "您單擊了【" + item.getTitle() + "】菜單項"
                                    , Toast.LENGTH_SHORT).show();
                    }
                    return true;
                }
            });

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