PopupMenu是Android中一个十分轻量级的组件。与PopupWindow相比,PopupMenu的可自定义的能力较小,但使用更加方便。

先上效果图:

Android:自定义PopupMenu的样式(显示图标/设置RadioButton图标)_第1张图片


本例要实现的功能如下:

1.强制显示菜单项的图标。

默认状态下,PopupMenu的图标是不显示的,并且Android没有为我们开放任何API去设置它的显示状态。为了显示菜单项的图标,可以自己重写PopupMenu并修改相关属性,也可以直接使用反射:

try {            Field field = popupMenu.getClass().getDeclaredField("mPopup");            field.setAccessible(true);            MenuPopupHelper mHelper = (MenuPopupHelper) field.get(popupMenu);            mHelper.setForceShowIcon(true);        } catch (IllegalAccessException | NoSuchFieldException e) {            e.printStackTrace();        }
2.在菜单项上添加 单选/复选 按钮:在menu的资源文件中使用group标签为item添加分组即可。

menu_popup.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto">    <group android:checkableBehavior="single">        <item            android:id="@+id/menu_setting_wifi"            android:title="使用WIFI"            android:orderInCategory="80"            android:icon="@drawable/menu_setting_wifi"            app:showAsAction="ifRoom" />        <item            android:id="@+id/menu_setting_gps"            android:title="使用GPS"            android:orderInCategory="90"            android:icon="@drawable/menu_setting_gps"            app:showAsAction="ifRoom" />    </group>    <group>        <item            android:id="@+id/menu_setting_userIcon"            android:title="设置头像"            android:icon="@drawable/menu_setting_usericon"            android:orderInCategory="91"            app:showAsAction="never" />    </group></menu>
其中,checkableBehavior有3个值可选:single,all,none,分别表示单选、复选、不可选。
3.为上述 单选/复选 按钮自定义图标。

PopupMenu会从当前的context中继承样式,因此可以通过设置Activity的样式来控制PopupMenu的样式。

<!--自定义PopupMenu上的RadioButton的样式-->    <style name="PopupMenuStyle" parent="AppTheme">        <item name="android:radioButtonStyle">@style/MenuRadioButtonStyle</item>    </style>    <style name="MenuRadioButtonStyle" parent="@android:style/Widget.CompoundButton.RadioButton">        <item name="android:button">@drawable/selector_menu_rb</item>    </style>
同时在manifest中为PopupMenu所属的Activity添加样式:
<activity            android:name=".PopupMenuActivity"            android:theme="@style/PopupMenuStyle" />

补充:也可以在初始话PopupMenu的时候直接设置样式。但是这种方式编译器会多次出现警告:Too many attribute references。因此不建议使用。

Context wrapper = new ContextThemeWrapper(activity, R.style.PopupMenuStyle);PopupMenu popupMenu = new PopupMenu(activity, ancher);

====== ======

Activity部分完整代码:

/** * 自定义PopupMenu * Created by hanj on 15-3-17. */public class PopupMenuActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        LinearLayout lin = new LinearLayout(this);        Button btn = new Button(this);        LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(                LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);        btn.setLayoutParams(p);        lin.addView(btn);        btn.setText("显示PopupMenu");        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                showPopupMenu(PopupMenuActivity.this, v);            }        });        setContentView(lin);    }    //当前选择的menuItem的id    private int checkedItemId = R.id.menu_setting_wifi;    private void showPopupMenu(final Context context, View ancher) {        PopupMenu popupMenu = new PopupMenu(context, ancher);        //引入菜单资源        popupMenu.inflate(R.menu.menu_popup);        //设置选中        popupMenu.getMenu().findItem(checkedItemId).setChecked(true);        //菜单项的监听        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {            @Override            public boolean onMenuItemClick(MenuItem menuItem) {                switch (menuItem.getItemId()) {                    case R.id.menu_setting_wifi:                        checkedItemId = R.id.menu_setting_wifi;                        Toast.makeText(context, "WIFI", Toast.LENGTH_SHORT).show();                        break;                    case R.id.menu_setting_gps:                        checkedItemId = R.id.menu_setting_gps;                        Toast.makeText(context, "GPS", Toast.LENGTH_SHORT).show();                        break;                    case R.id.menu_setting_userIcon:                        Toast.makeText(context, "USER_ICON", Toast.LENGTH_SHORT).show();                        break;                }                return true;            }        });        //使用反射,强制显示菜单图标        try {            Field field = popupMenu.getClass().getDeclaredField("mPopup");            field.setAccessible(true);            MenuPopupHelper mHelper = (MenuPopupHelper) field.get(popupMenu);            mHelper.setForceShowIcon(true);        } catch (IllegalAccessException | NoSuchFieldException e) {            e.printStackTrace();        }        //显示PopupMenu        popupMenu.show();    }}








更多相关文章

  1. [Android][主题和样式]
  2. 太激动!Android修改全局字体样式,替换整个APP字体
  3. 【Android自学笔记】对应资源文件夹中的图标尺寸
  4. Android 图标设计标准与原则
  5. android自定义button样式
  6. 自定义dialog样式
  7. Android 主题和样式

随机推荐

  1. Android存储权限
  2. 用PC应用程序通过USB读写Andriod里面的数
  3. Android 控件之DatePicker,TimePicker,Ca
  4. 解决Could not find method android() fo
  5. Android禁止横屏竖屏切换
  6. 改变android程序head样式
  7. android的Notification折叠
  8. [ZZ]Android UI Automated Testing
  9. Android初小试---一分钟傻瓜式打包
  10. android studio 提示no android sdk foun