菜单Menu

作者: olaH | 来源:发表于2017-10-31 22:25 被阅读0次

    前言

    星光不问赶路人,时间不负有心人。

    选项菜单和子菜单

    Android应用中的菜单默认是看不见的,只有当用户按下手机上的“MENU”键时,系统才会显示该应用关联的菜单,这种菜单叫选项菜单。
    从Android3.0开始,Android并不要求手机设备上必须提供MENU按键,在这样的情况下,Android推荐使用ActionBar来代替菜单。
    下面我来简单介绍一下Menu接口定义的方法。
    • MenuItem add(int titleRes):添加一个新的菜单项。
    • MenuItem add(int groupId, int itemId, int order, CharSequence title):添加一个新的处于groupId组的菜单项。
    • MenuItem add(CharSequence title):添加一个新的菜单项。
    • SubMenu addSubMenu(int titleRes):添加一个新的子菜单。
    • SubMenu add(int groupId, int itemId, int order, CharSequence title):添加一个新的处于groupId组的子菜单。
    • SubMenu add(CharSequence title):添加一个新的子菜单。

    代码示例

    MainActiv.java
    public class MainActivity extends Activity {
    
        //定义“字体大小”菜单项的标识
        final int FONT_10 = 0x111;
        final int FONT_12 = 0x112;
        final int FONT_14 = 0x113;
        final int FONT_16 = 0x114;
        final int FONT_18 = 0x115;
        //定义“普通菜单项”的标识
        final int PLAIN_ITEM = 0x11b;
        //定义“字体颜色”菜单项的标识
        final int FONT_RED = 0x116;
        final int FONT_BLUE = 0x117;
        final int FONT_GREEN = 0x118;
    
        private EditText edit;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.menu);
            edit = (EditText) findViewById(R.id.txt);
        }
    
        //当用户单击MENU建时触发该方法
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
    
    
            //向menu中添加“字体大小”的子菜单
            SubMenu fontMenu = menu.addSubMenu("字体大小");
            //设置菜单的图标
            fontMenu.setIcon(R.drawable.ic_launcher);
            //设置菜单头的图标
            fontMenu.setHeaderIcon(R.drawable.ic_launcher);
            //设置菜单头的标题
            fontMenu.setHeaderTitle("选择字体大小");
            fontMenu.add(0, FONT_10, 0, "10号字体");
            fontMenu.add(0, FONT_12, 0, "12号字体");
            fontMenu.add(0, FONT_14, 0, "14号字体");
            fontMenu.add(0, FONT_16, 0, "16号字体");
            fontMenu.add(0, FONT_18, 0, "18号字体");
            //向menu中添加“普通菜单项”
            menu.add(0, PLAIN_ITEM, 0, "普通菜单项");
            //向menu中添加“字体颜色”的子菜单
            SubMenu colorMenu = menu.addSubMenu("字体颜色");
            colorMenu.setIcon(R.drawable.ic_launcher);
            //设置菜单头的图标
            colorMenu.setHeaderIcon(R.drawable.ic_launcher);
            //设置菜单头的标题
            colorMenu.setHeaderTitle("选择文字颜色");
            colorMenu.add(0, FONT_RED, 0, "红色");
            colorMenu.add(0, FONT_BLUE, 0, "蓝色");
            colorMenu.add(0, FONT_GREEN, 0, "绿色");
    
            return super.onCreateOptionsMenu(menu);
        }
    
        //选项菜单的菜单项被单击后的回调方法
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            //判断单击的是哪个菜单项,并有针对性地做出响应
            switch (item.getItemId()) {
            case FONT_10:
                edit.setTextSize(10 * 2);
                break;
            case FONT_12:
                edit.setTextSize(12 * 2);
                break;
            case FONT_14:
                edit.setTextSize(14 * 2);
                break;
            case FONT_16:
                edit.setTextSize(16 * 2);
                break;
            case FONT_18:
                edit.setTextSize(18 * 2);
                break;
            case FONT_RED:
                edit.setTextColor(Color.RED);
                break;
            case FONT_BLUE:
                edit.setTextColor(Color.BLUE);
                break;
            case FONT_GREEN:
                edit.setTextColor(Color.GREEN);
                break;
            case PLAIN_ITEM:
                Toast.makeText(MainActivity.this, "您单击了普通菜单项", Toast.LENGTH_SHORT).show();
                break;
    
            default:
                break;
            }
            return true;
        }
    }
    

    效果

    Screenshot_20171024-164807.png
    单击颜色菜单项
    Screenshot_20171024-164812.png

    上下文菜单(ContextMenu)

    Android用ContextMenu来代表上下文菜单,为Android应用开发上下文菜单与开发选项菜单的方法基本相似。而开发上下文菜单与开发选项菜单的区别在于:开发上下文菜单不是重写onCreateOptionsMenu(Menu menu)方法,而是重写onCreateContextMenu(ContextMenu menu,View source, ContextMenu.ContextMenuInfo menuInfo)。其中source参数代表触发上下文菜单的组件。
    开发上下文菜单的步骤如下。
    1. 重写Activity的onCreateContextMenu(ContextMenu menu, View source, ContextMenu.Context MenuInfo menuInfo)方法。

    2. 调用Activity的registerForContextMenu(View v)方法为view组件注册上下文菜单。

    3. 如果希望应用程序能为菜单项提供响应,则可以重写onContextItemSelected(MenuItem mi)方法,或为指定菜单项绑定事件监听器。

    代码示例

    MainActivity.java
    public class MainActivity extends Activity {
    
        //为每个菜单定义一个标识
        final int MENU1 = 0x111;
        final int MENU2 = 0x112;
        final int MENU3 = 0x113;
    
    
        private TextView txt;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.menu);
            txt = (TextView) findViewById(R.id.txt);
            //为文本框注册上下文菜单
            registerForContextMenu(txt);
        }
        //创建上下午菜单时触发该方法
    
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    
            menu.add(0, MENU1, 0, "红色");
            menu.add(0, MENU2, 0, "蓝色");
            menu.add(0, MENU3, 0, "绿色");
            //将三个菜单项设为单选菜单项
            menu.setGroupCheckable(0, true, true);
            //设置上下文菜单的标题、图标
            menu.setHeaderIcon(R.drawable.ic_launcher);
            menu.setHeaderTitle("选择背景色");
        }
    
        //上下文菜单的菜单项被单击时触发该方法
    
        @Override
        public boolean onContextItemSelected(MenuItem item) {
    
            switch (item.getItemId()) {
            case MENU1:
                item.setChecked(true);
                txt.setBackgroundColor(Color.RED);
                break;
            case MENU2:
                item.setChecked(true);
                txt.setBackgroundColor(Color.GREEN);
                break;
            case MENU3:
                item.setChecked(true);
                txt.setBackgroundColor(Color.BLUE);
                break;
    
            default:
                break;
            }
    
            return true;
        }
    }
    

    效果

    Screenshot_20171025-092834.png

    使用XML文件定义菜单

    一般推荐使用XML资源文件来定义菜单,这种方式可以提供更好的解耦。
    • <item.../>:定义菜单项
    • <group.../>:将多个<item.../>定义的菜单项包装成一个菜单组。用于控制整组菜单的行为,该元素可指定如下常用属性。
      1. checkableBehavior:指定该组菜单的选择行为。可指定为none(不可选)、all(多选)、single(单选)。
      2. menuCategory:对菜单进行分类,指定菜单的优先级。
      3. visible:指定该组菜单是否可见。
      4. enable:指定该组菜单是否可用。

    代码示例

    contextmenu.xml
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
        <!-- 定义一组单选菜单项 -->
        <group android:checkableBehavior="single">
            <!-- 定义三个菜单项 --><!-- 字符快捷键 -->
            <item
                android:id="@+id/red"
                android:title="red_title"
                android:alphabeticShortcut="r"
                />
            <item
                android:id="@+id/green"
                android:title="green_title"
                android:alphabeticShortcut="g"
                />
            <item
                android:id="@+id/blue"
                android:title="blue_title"
                android:alphabeticShortcut="b"
                />
        </group>
    
    </menu>
    
    
    main.xml
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        tools:context="com.zdf.uidemo9.MainActivity" >
    
        <item
            android:icon="@drawable/ic_launcher"
            android:title="font_size">
            <menu>
    
                <!-- 定义一组单选菜单项 -->
                <group android:checkableBehavior="single" >
    
                    <!-- 定义多个菜单项 -->
                    <item
                        android:id="@+id/font_10"
                        android:title="font_10"/>
                    <item
                        android:id="@+id/font_12"
                        android:title="font_12"/>
                    <item
                        android:id="@+id/font_14"
                        android:title="font_14"/>
                    <item
                        android:id="@+id/font_16"
                        android:title="font_16"/>
                    <item
                        android:id="@+id/font_18"
                        android:title="font_18"/>
                </group>
            </menu>
        </item>
        <!-- 定义一个普通菜单项 -->
        <item
            android:id="@+id/plain_item"
            android:title="plain_item"/>
        <item
            android:icon="@drawable/ic_launcher"
            android:title="font_color">
            <menu>
                <!-- 定义一组普通菜单项 -->
                <group>
                    <!-- 定义三个菜单项 -->
                    <item
                        android:id="@+id/red_font"
                        android:title="red_title"
                        />
                    <item
                        android:id="@+id/green_font"
                        android:title="green_title"
                        />
                    <item
                        android:id="@+id/blue_font"
                        android:title="blue_title"
                        />
                </group>
            </menu>
        </item>
    </menu>
    
    MainActivity.java
    public class MainActivity extends Activity {
    
        private TextView txt;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.menu);
            txt = (TextView) findViewById(R.id.txt);
            //为文本框注册上下文菜单
            registerForContextMenu(txt);
        }
    
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
    
            MenuInflater inflator = new MenuInflater(this);
            inflator.inflate(R.menu.main, menu);
            return super.onCreateOptionsMenu(menu);
        }
        //创建上下文菜单时触发该方法
    
    
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    
            MenuInflater inflator = new MenuInflater(this);
            //装填R。menu。context对应的菜单,并添加到menu中
            inflator.inflate(R.menu.context, menu);
            menu.setHeaderTitle("请选择背景色");
    
        }
    
        //上下文菜单的菜单项被单击时触发该方法
    
        @Override
        public boolean onContextItemSelected(MenuItem item) {
    
            item.setChecked(true);
            switch (item.getItemId()) {
            case R.id.red:
                item.setChecked(true);
                txt.setBackgroundColor(Color.RED);
                break;
            case R.id.green:
                item.setChecked(true);
                txt.setBackgroundColor(Color.GREEN);
                break;
            case R.id.blue:
                item.setChecked(true);
                txt.setBackgroundColor(Color.BLUE);
                break;
            }
            return true;
        }
    
    
    
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            if(item.isCheckable())
            {
                //勾选该菜单项
                item.setChecked(true);
            }
            //判断单击的是哪个菜单
            switch (item.getItemId()) {
            case R.id.font_10:
                txt.setTextSize(10 * 2);
                break;
            case R.id.font_12:
                txt.setTextSize(12 * 2);
                break;
            case R.id.font_14:
                txt.setTextSize(14 * 2);
                break;
            case R.id.font_16:
                txt.setTextSize(16 * 2);
                break;
            case R.id.font_18:
                txt.setTextSize(18 * 2);
                break;
            case R.id.red_font:
                txt.setTextColor(Color.RED);
                item.setChecked(true);
                break;
            case R.id.green_font:
                txt.setTextColor(Color.GREEN);
                item.setChecked(true);
                break;
            case R.id.blue_font:
                txt.setTextColor(Color.BLUE);
                item.setChecked(true);
                break;
            case R.id.plain_item:
                Toast.makeText(MainActivity.this, "您单击了普通菜单项", Toast.LENGTH_SHORT).show();
                break;
            }
            return true;
        }
    }
    
    效果和前面几个例子一样。

    PopupMenu组件

    PopupMenu代表弹出式菜单,它会在指定组件上弹出PopupMenu,在默认情况下,PopupMenu会显示在该组件的下方或者上方。使用PopupMenu创建菜单的步骤非常简单。
    • 调用new PopupMenu(Context context,View anchor)创建下拉菜单,anchor代表要激发该弹出菜单的组件
    • 调用MenuInflater的inflate()方法将菜单资源填充到PopupMenu中。
    • 调用PopupMenu的show()方法显示弹出式菜单。

    代码示例

    main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onPopupButtonClick"
            android:text="单击"
            />
    </LinearLayout>
    
    
    popup_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
        <item
            android:title="查找"
            />
        <item
            android:title="添加"
            />
        <item
            android:title="编辑"
            />
        <item
            android:id="@+id/exit"
            android:title="隐藏菜单"
            />
    </menu>
    
    MainActivity.java
    public class MainActivity extends Activity {
    
        PopupMenu popup = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
        }
    
        public void onPopupButtonClick(View button)
        {
            //创建PopupMenu对象
            popup = new PopupMenu(this, button);
            //将R。menu。popup_menu菜单资源加载到popup菜单中
            getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());
            //为popup菜单的菜单项单击事件绑定事件监听器
            popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
    
                @Override
                public boolean onMenuItemClick(MenuItem item) {
    
                    switch (item.getItemId()) {
                    case R.id.exit:
                        //隐藏对话框
                        popup.dismiss();
                        break;
    
                    default:
                        Toast.makeText(MainActivity.this, "您单击了【" + item.getTitle() + "】菜单项", Toast.LENGTH_SHORT).show();
                        break;
                    }
                    return true;
                }
            });
            popup.show();
        }
    }
    

    效果

    Screenshot_20171025-103504.png

    相关文章

      网友评论

        本文标题:菜单Menu

        本文链接:https://www.haomeiwen.com/subject/rwvipxtx.html