Menu

简介: Menu

菜单的基本使用


官方API

menu-resource

在Android中,菜单被分为如下三种,选项菜单(OptionsMenu)、上下文菜单(ContextMenu)和子菜单(SubMenu)


OptionsMenu


效果图


20160314111519082.gif

说明

重写两个方法 public boolean onCreateOptionsMenu(Menu menu):调用OptionMenu,在这里完成菜单初始化,只会在第一次初始化菜单时调用

public boolean onOptionsItemSelected(MenuItem item):菜单项被选中时触发,这里完成事件处理

当然除了上面这两个方法我们可以重写外我们还可以重写这三个方法:


public void onOptionsMenuClosed(Menu menu):菜单关闭会调用该方法

public boolean onPrepareOptionsMenu(Menu menu):选项菜单显示前会调用该方法, 可在这里进行菜单的调整(动态加载菜单列表)

public boolean onMenuOpened(int featureId, Menu menu):选项菜单打开以后会调用这个方法

加载菜单的方式有两种,

一种是直接通过编写菜单XML文件,然后调用: getMenuInflater().inflate(R.menu.XXXX, menu);加载菜单

或者通过代码动态添加,onCreateOptionsMenu的参数menu,调用add方法添加 菜单,add(菜单项的组号,ID,排序号,标题),另外如果排序号是按添加顺序排序的话都填0即可!


Code

package com.turing.base.activity.menu;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import com.turing.base.R;
/**
 * 最常用的就是选项菜单(optionsMenu),
 * 该菜单在点击 menu 按键 后会在对应的Activity底部显示出来。(4.4以前)
 * Activity菜单机制 ,Activity有一套机制来实现对菜单的管理 就是下面重写的几个方法
 */
public class OPtionMenuDemoAct extends AppCompatActivity {
    private TextView textView;
    //1.定义不同颜色的菜单项的标识:
    final private int RED = 110;
    final private int GREEN = 111;
    final private int BLUE = 112;
    final private int YELLOW = 113;
    final private int GRAY= 114;
    final private int CYAN= 115;
    final private int BLACK= 116;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_option_menu_demo);
        textView = (TextView) findViewById(R.id.id_tv_optionMenuText);
    }
    /**
     * 两种方式  1.通过menu的xml加载,2 通过代码动态创建
     *
     * @param menu
     * @return
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        /**
         * 此方法用于初始化菜单,其中menu参数就是即将要显示的Menu实例。 返回true则显示该menu,false 则不显示;
         * (只会在第一次初始化菜单时调用)
         * Inflate the menu; this adds items to the action bar  if it is present.
         */
        /**
         * 通过xml加载菜单
         *  getMenuInflater().inflate(R.menu.options_menu, menu);
         调用Activity的getMenuInflater()得到一个MenuInflater,
         使用inflate方法来把布局文件中的定义的菜单 加载给 第二个参数所对应的menu对象
         如果需要设置图片,可以在xml中设置 android:icon="@drawable/setting"
         高版本的SDK,即使设置了 Icon,也不会显示的。低版本的会显示
         */
        //getMenuInflater().inflate(R.menu.menu_main,menu);
        /**
         *
         * 第二种方式: 通过代码动态创建
         *
         *  menu.add((int groupId, int itemId, int order, charsequence title) .setIcon(drawable ID)
         add()方法的四个参数,依次是:
         1、组别,如果不分组的话就写Menu.NONE,
         2、Id,这个很重要,Android根据这个Id来确定不同的菜单
         3、顺序,哪个菜单项在前面由这个参数的大小决定
         4、文本,菜单项的显示文本
         add()方法返回的是MenuItem对象,调用其setIcon()方法,为相应MenuItem设置Icon
         高版本的SDK,即使设置了 Icon,也不会显示的。2.3低版本的会显示
         */
        // 高版本的SDK,即使设置了 Icon,也不会显示的。低版本的会显示
        menu.add(1,RED,4,"红色").setIcon(R.drawable.flag_mark_red);
        menu.add(1,GREEN,2,"绿色").setIcon(R.drawable.flag_mark_green);
        menu.add(1,BLUE,3,"蓝色").setIcon(R.drawable.flag_mark_blue);
        menu.add(1,YELLOW,1,"黄色").setIcon(R.drawable.flag_mark_yellow);
        menu.add(1,GRAY,5,"灰色").setIcon(R.drawable.flag_mark_gray);
        menu.add(1,CYAN,6,"蓝绿色").setIcon(R.drawable.gur_project_10);
        menu.add(1,BLACK,7,"黑色").setIcon(R.drawable.gur_project_5);
        // 返回true则显示该menu,false 则不显示;
        return true;
    }
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        /**
         * 在onCreateOptionsMenu执行后,菜单被显示前调用;
         * 如果菜单已经被创建,则在菜单显示前被调用。
         * 同样的,返回true则显示该menu,false 则不显示;
         * (可以通过此方法动态的改变菜单的状态,比如加载不同的菜单等)
         */
        return super.onPrepareOptionsMenu(menu);
    }
    @Override
    public void onOptionsMenuClosed(Menu menu) {
        /**
         * 每次菜单被关闭时调用.
         * (菜单被关闭有三种情形,menu按钮被再次点击、back按钮被点击或者用户选择了某一个菜单项)
         */
        super.onOptionsMenuClosed(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        /**
         * 菜单项被点击时调用,也就是菜单项的监听方法。
         * 通过这几个方法,可以得知,对于Activity,同一时间只能显示和监听一个Menu 对象。
         */
        switch ( item.getItemId()){
            case RED:  //对应的ID就是在add方法中所设定的Id
                textView.setTextColor(Color.RED);
                break;
            case GREEN:
                textView.setTextColor(Color.GREEN);
                break;
            case BLUE:
                textView.setTextColor(Color.BLUE);
                break;
            case YELLOW:
                textView.setTextColor(Color.YELLOW);
                break;
            case GRAY:
                textView.setTextColor(Color.GRAY);
                break;
            case CYAN:
                textView.setTextColor(Color.CYAN);
                break;
            case BLACK:
                textView.setTextColor(Color.BLACK);
                break;
        }
        /**
         * 如果是通过xml加载的菜单选项,那么Id就是布局文件中定义的Id,在用R.id.XXX的方法获取出来
         */
        return super.onOptionsItemSelected(item);
    }
}


在Android 3.0或者更高的版本,则是通过3.0引入的ActionBar中的setting菜单:

在5.0以上的版本则是在ToolBar中的,点击后出一个溢出式的菜单样式


ContextMenu

效果图

20160314112132671.gif


说明


长按某个View后出现的菜单,我们需要为这个View注册上下文菜单!


操作步骤


Step 1:重写onCreateContextMenu()方法

Step 2:为view组件注册上下文菜单,使用 - registerForContextMenu()方法,参数是View

Step 3:重写onContextItemSelected()方法为菜单项指定事件监听器

在这里我们通过xml来加载,当然了也可以用代码创建~


Code

res\menu\menu_context.xml


<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 定义一组单选按钮 -->
    <!-- checkableBehavior的可选值由三个:
        single设置为单选,
        all为多选,none为普通选项 -->
    <group android:checkableBehavior="none">
        <item
            android:id="@+id/op1"
            android:title="选项一" />
        <item
            android:id="@+id/op2"
            android:title="选项二" />
        <item
            android:id="@+id/op3"
            android:title="选项三" />
    </group>
</menu>


ContextMenuDemoAct.java

package com.turing.base.activity.menu;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import com.turing.base.R;
import java.util.ArrayList;
import java.util.List;
/**
 * 长按某个View后出现的菜单,我们需要为这个View注册上下文菜单!
 * <p/>
 * 使用的流程如下:
 * Step 1:重写onCreateContextMenu()方法
 * Step 2:为view组件注册上下文菜单,使用registerForContextMenu()方法,参数是View
 * Step 3:重写onContextItemSelected()方法为菜单项指定事件监听器
 *
 *
 *
 * 上下文菜单无法显示图标!
 */
public class ContextMenuDemoAct extends AppCompatActivity {
    private ListView listView;
    private List dataList = new ArrayList();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_context_menu_demo);
        listView = (ListView) findViewById(R.id.id_listView);
        for (int i = 0; i < 20; i++) {
            dataList.add(i);
        }
        ArrayAdapter adapter = new ArrayAdapter(ContextMenuDemoAct.this,
                android.R.layout.simple_list_item_1, dataList);
        listView.setAdapter(adapter);
        registerForContextMenu(listView);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(ContextMenuDemoAct.this, "onItemClick", Toast.LENGTH_SHORT).show();
            }
        });
    }
    //重写上下文菜单的创建方法
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        getMenuInflater().inflate(R.menu.menu_context,menu);
        super.onCreateContextMenu(menu, v, menuInfo);
    }
    //上下文菜单被点击是触发该方法
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.op1:
                Toast.makeText(this,"op1",Toast.LENGTH_SHORT).show();
                break;
            case R.id.op2:
                Toast.makeText(this,"op2",Toast.LENGTH_SHORT).show();
                break;
            case R.id.op3:
                Toast.makeText(this,"op3",Toast.LENGTH_SHORT).show();
                break;
        }
        return true;
    }
}


SubMenu

效果图

20160314112808378.gif


说明

所谓的子菜单只是在<item>中又嵌套了一层<menu>,仅此而已。

Code

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/submenu"
        android:title="子菜单使用演示~">
        <menu>
            <group android:checkableBehavior="none">
                <item
                    android:id="@+id/one"
                    android:title="子菜单一" />
                <item
                    android:id="@+id/two"
                    android:title="子菜单二" />
                <item
                    android:id="@+id/three"
                    android:title="子菜单三" />
            </group>
        </menu>
    </item>
</menu>
package com.turing.base.activity.menu;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.turing.base.R;
/**
 * 所谓的子菜单只是在<**item**>中又嵌套了一层<**menu**>而已
 * <p/>
 * 在Java代码中添加子菜单的话,可以调用addSubMenu()
 * 比如:SubMenu file = menu.addSubMenu("文件");file还需要addItem添加菜单项!
 */
public class SubMenuDemoAct extends AppCompatActivity {
    private TextView textView ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub_menu_demo);
        textView = (TextView) findViewById(R.id.id_tv_info);
        registerForContextMenu(textView);
    }
    public void onCreateContextMenu(ContextMenu menu, View v,
                                    ContextMenu.ContextMenuInfo menuInfo) {
        //子菜单部分:
        MenuInflater inflator = new MenuInflater(this);
        inflator.inflate(R.menu.menu_sub, menu);
        super.onCreateContextMenu(menu, v, menuInfo);
    }
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.one:
                Toast.makeText(SubMenuDemoAct.this, "你点击了子菜单一", Toast.LENGTH_SHORT).show();
                break;
            case R.id.two:
                item.setCheckable(true);
                Toast.makeText(SubMenuDemoAct.this, "你点击了子菜单二", Toast.LENGTH_SHORT).show();
                break;
            case R.id.three:
                Toast.makeText(SubMenuDemoAct.this, "你点击了子菜单三", Toast.LENGTH_SHORT).show();
                item.setCheckable(true);
                break;
        }
        return true;
    }
}


PopupMenu

效果图


20160314113041490.gif


说明


一个类似于PopupWindow的控件,他可以很方便的在指定View下显示一个弹出菜单,而且 他的菜单选项可以来自于Menu资源。


Code



<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/see" android:title="查看" />
    <item android:id="@+id/download" android:title="下载" />
</menu>

PopupMenuDemoAct.java

package com.turing.base.activity.menu;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.PopupMenu;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.turing.base.R;
public class PopupMenuDemoAct extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_popup_menu_demo);
    }
    public void showPopupMenu(View view ){
        // 初始化PopupMenu控件
        PopupMenu popup = new PopupMenu(PopupMenuDemoAct.this,view);
        // 加载菜单选项
        popup.getMenuInflater().inflate(R.menu.menu_pop, popup.getMenu());
        // 设置显示位置
        popup.setGravity(Gravity.RIGHT);
        // 设置监听事件
        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()){
                    case R.id.see:
                        Toast.makeText(PopupMenuDemoAct.this, "查看",
                                Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.download:
                        Toast.makeText(PopupMenuDemoAct.this,"下载",
                                Toast.LENGTH_SHORT).show();
                        break;
                }
                return true;
            }
        });
        // 显示PopupMenu控件
        popup.show();
    }
}


自定义布局菜单

效果图

20160314151548266.gif

说明

替换Android菜单实现自定义菜单风格

这里menuView是自定的菜单风格,是一个View。

最重要的是:onCreateOptionsMenu + onMenuOpened

/** 
 * 创建MENU 
 */
public boolean onCreateOptionsMenu(Menu menu) { 
   menu.add("menu");// 必须创建一项 
   return super.onCreateOptionsMenu(menu); 
} 
/** 
 * 拦截MENU事件,显示自己的菜单 
 */
@Override 
public boolean onMenuOpened(int featureId, Menu menu) { 
   if (menuDialog == null) { 
    menuDialog = new AlertDialog.Builder(this).setView(menuView).show(); 
   } else { 
    menuDialog.show(); 
   } 
   return false;// 返回为true 则显示系统menu 
}

Code

CustomizeMenu.java

package com.turing.base.activity.menu;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.SimpleAdapter;
import com.turing.base.R;
import java.util.ArrayList;
import java.util.HashMap;
public class CustomizeMenu extends AppCompatActivity {
    private boolean isMore = false;// menu菜单翻页控制
    AlertDialog menuDialog;// menu菜单Dialog
    GridView menuGrid;
    View menuView;
    private final int ITEM_SEARCH = 0;// 搜索
    private final int ITEM_FILE_MANAGER = 1;// 文件管理
    private final int ITEM_DOWN_MANAGER = 2;// 下载管理
    private final int ITEM_FULLSCREEN = 3;// 全屏
    private final int ITEM_MORE = 11;// 菜单
    /**
     * 菜单图片
     **/
    int[] menu_image_array = {
            R.drawable.menu_search,
            R.drawable.menu_filemanager, R.drawable.menu_downmanager,
            R.drawable.menu_fullscreen, R.drawable.menu_inputurl,
            R.drawable.menu_bookmark, R.drawable.menu_bookmark_sync_import,
            R.drawable.menu_sharepage, R.drawable.menu_quit,
            R.drawable.menu_nightmode, R.drawable.menu_refresh,
            R.drawable.menu_more};
    /**
     * 菜单文字
     **/
    String[] menu_name_array = {
            "搜索", "文件管理", "下载管理", "全屏", "网址", "书签",
            "加入书签", "分享页面", "退出", "夜间模式", "刷新", "更多"};
    /**
     * 菜单图片2
     **/
    int[] menu_image_array2 = {
            R.drawable.menu_auto_landscape,
            R.drawable.menu_penselectmodel, R.drawable.menu_page_attr,
            R.drawable.menu_novel_mode, R.drawable.menu_page_updown,
            R.drawable.menu_checkupdate, R.drawable.menu_checknet,
            R.drawable.menu_refreshtimer, R.drawable.menu_syssettings,
            R.drawable.menu_help, R.drawable.menu_about, R.drawable.menu_return};
    /**
     * 菜单文字2
     **/
    String[] menu_name_array2 = {
            "自动横屏", "笔选模式", "阅读模式", "浏览模式", "快捷翻页",
            "检查更新", "检查网络", "定时刷新", "设置", "帮助", "关于", "返回"};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_customize_menu);
        menuView = View.inflate(this, R.layout.gridview_menu, null);
        // 创建AlertDialog
        menuDialog = new AlertDialog.Builder(this).create();
        menuDialog.setView(menuView);
        menuDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
            public boolean onKey(DialogInterface dialog, int keyCode,
                                 KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_MENU)// 监听按键
                    dialog.dismiss();
                return false;
            }
        });
        menuGrid = (GridView) menuView.findViewById(R.id.gridview);
        menuGrid.setAdapter(getMenuAdapter(menu_name_array, menu_image_array));
        /** 监听menu选项 **/
        menuGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                                    long arg3) {
                switch (arg2) {
                    case ITEM_SEARCH:// 搜索
                        break;
                    case ITEM_FILE_MANAGER:// 文件管理
                        break;
                    case ITEM_DOWN_MANAGER:// 下载管理
                        break;
                    case ITEM_FULLSCREEN:// 全屏
                        break;
                    case ITEM_MORE:// 翻页
                        if (isMore) {
                            menuGrid.setAdapter(getMenuAdapter(menu_name_array2,
                                    menu_image_array2));
                            isMore = false;
                        } else {// 首页
                            menuGrid.setAdapter(getMenuAdapter(menu_name_array,
                                    menu_image_array));
                            isMore = true;
                        }
                        menuGrid.invalidate();// 更新menu
                        menuGrid.setSelection(ITEM_MORE);
                        break;
                }
            }
        });
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // 必须创建一项,否则不显示...
        menu.add("menu");
        return super.onCreateOptionsMenu(menu);
    }
    private SimpleAdapter getMenuAdapter(String[] menuNameArray,
                                         int[] imageResourceArray) {
        ArrayList<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>();
        for (int i = 0; i < menuNameArray.length; i++) {
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("itemImage", imageResourceArray[i]);
            map.put("itemText", menuNameArray[i]);
            data.add(map);
        }
        SimpleAdapter simperAdapter = new SimpleAdapter(this, data,
                R.layout.item_menu, new String[]{"itemImage", "itemText"},
                new int[]{R.id.item_image, R.id.item_text});
        return simperAdapter;
    }
    /**
     * 自定义布局
     * @param featureId
     * @param menu
     * @return
     */
    @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        if (menuDialog == null) {
            menuDialog = new AlertDialog.Builder(this).setView(menuView).show();
        } else {
            menuDialog.show();
        }
        return false;// 返回为true 则显示系统menu
    }
}

gridview_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<GridView
         android:id="@+id/gridview"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:numColumns="4"
         android:verticalSpacing="10dip"
         android:horizontalSpacing="10dip"
         android:stretchMode="columnWidth"
         android:gravity="center"
         />
</LinearLayout>


item_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/RelativeLayout_Item"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="5dip">
    <ImageView
        android:id="@+id/item_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:src="@drawable/menu_about"/>
    <TextView
        android:id="@+id/item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/item_image"
        android:layout_centerHorizontal="true"
        android:text="选项"></TextView>
</RelativeLayout>


相关文章
|
XML Java Android开发
菜单(Menu)
本章给大家带来的是Android中的Menu(菜单),而在Android中的菜单有如下几种: OptionMenu:选项菜单,android中最常见的菜单,通过Menu键来调用 SubMenu:子菜单,android中点击子菜单将弹出一个显示子菜单项的悬浮框,子菜单不支持嵌套,即不能包括其他子菜单 ContextMenu:上下文菜单,通过长按某个视图组件后出现的菜单,该组件需注册上下文菜单本节我们来依依学习这几种菜单的用法~ PS:官方文档:menus 1.OptionMenu(选项菜单) 1)如何使用OptionMenu? 答:非常简单,重写两个方法就好,其实这两个方法我们在创
112 0
在 fragment 中使用 Toolbar 的 menu
在 fragment 中使用 Toolbar 的 menu
|
Shell 网络架构
|
XML Android开发 数据格式
菜单Menu
前言 星光不问赶路人,时间不负有心人。 选项菜单和子菜单 Android应用中的菜单默认是看不见的,只有当用户按下手机上的“MENU”键时,系统才会显示该应用关联的菜单,这种菜单叫选项菜单。
1027 0
根据Tcode查询Menu Path的Tcode
据说从4.6版本开始支持这个功能。 这个Tcode为 SEARCH_SAP_MENU。 可以试试SU01,一共有四个PATH。Accounting-&gt;Enterprise Controlling-&gt;EIS-&gt;Environment-&gt;Confi...
834 0
|
Android开发
menu item icon in toolbar overflow menu
stackoverflow解决 overflow menu的几个Item都不显示icon 贴一部分menu &lt;item android:id="@+id/action_zone" android:title="@string/zone" android:orderInCategory="90" andro
1223 0