前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

Menu

作者头像
小小工匠
发布2021-08-16 10:22:42
1K0
发布2021-08-16 10:22:42
举报
文章被收录于专栏:小工匠聊架构

菜单的基本使用

官方API

menu-resource

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

OptionsMenu

效果图

这里写图片描述
这里写图片描述

说明

  • 重写两个方法 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

代码语言:javascript
复制
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

效果图

这里写图片描述
这里写图片描述

说明

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

操作步骤

  • Step 1:重写onCreateContextMenu()方法
  • Step 2:为view组件注册上下文菜单,使用 - registerForContextMenu()方法,参数是View
  • Step 3:重写onContextItemSelected()方法为菜单项指定事件监听器

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

Code

res\menu\menu_context.xml

代码语言:javascript
复制
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    
    
    <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

代码语言:javascript
复制
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注册上下文菜单!
 * 

SubMenu

效果图

这里写图片描述
这里写图片描述

说明

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

Code

menu_sub.xml

代码语言:javascript
复制
<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>

SubMenuDemoAct.java

代码语言:javascript
复制
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**>而已
 * 

PopupMenu

效果图

这里写图片描述
这里写图片描述

说明

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

Code

menu_pop.xml

代码语言:javascript
复制
<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

代码语言:javascript
复制
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();
    }
}

自定义布局菜单

效果图

这里写图片描述
这里写图片描述

说明

替换Android菜单实现自定义菜单风格 这里menuView是自定的菜单风格,是一个View。

最重要的是:onCreateOptionsMenu + onMenuOpened

代码语言:javascript
复制
/** 
 * 创建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

代码语言:javascript
复制
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> data = new ArrayList>();
        for (int i = 0; i < menuNameArray.length; i++) {
            HashMap map = new HashMap();
            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

代码语言:javascript
复制
<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

代码语言:javascript
复制
<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>

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016/03/13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 菜单的基本使用
  • OptionsMenu
    • 效果图
      • 说明
        • Code
        • ContextMenu
          • 效果图
            • 说明
              • 操作步骤
            • Code
              • res\menu\menu_context.xml
              • ContextMenuDemoAct.java
          • SubMenu
            • 效果图
              • 说明
                • Code
                  • menu_sub.xml
                  • SubMenuDemoAct.java
              • PopupMenu
                • 效果图
                  • 说明
                    • Code
                      • menu_pop.xml
                      • PopupMenuDemoAct.java
                  • 自定义布局菜单
                    • 效果图
                      • 说明
                        • Code
                          • CustomizeMenu.java
                          • gridview_menu.xml
                          • item_menu.xml
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档