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








  • 相关阅读:
    如何快速发现网站恶意镜像与网页劫持?
    最牛「CSRF防护」,带你进入大虾们的圈子!
    安全无小事:如何给企业用户数据上把锁?
    PHP 7 探针的安装与测试
    如何使用 Docker、ECS、Terraform 重建基础架构?
    应用安全技术趋势之 Top 5
    第77节:Java中的事务和数据库连接池和DBUtiles
    第76节:Java中的基础知识
    第76节:Java中的基础知识
    第75节:Java的中的JSP,EL和JSTL
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5077749.html
Copyright © 2011-2022 走看看