zoukankan      html  css  js  c++  java
  • Android:自己定义PopupMenu的样式(显示图标/设置RadioButton图标)

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

    先上效果图:



    本例要实现的功能例如以下:

    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.在菜单项上加入 单选/复选 button:在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.为上述 单选/复选 button自己定义图标。

    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();
        }
    }








  • 相关阅读:
    61. 最长不含重复字符的子字符串
    60. 礼物的最大价值 (未理解)
    59. 把数字翻译成字符串
    58. 把数组排成最小的数
    57. 数字序列中某一位的数字 (不懂)
    spring data jpa 官方文档
    idea 编译报错 源发行版 1.8 需要目标发行版 1.8
    idea maven 依赖报错 invalid classes root
    solr
    spring boot 官方文档
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5077749.html
Copyright © 2011-2022 走看看