Android----菜单的使用

  上一篇《Android菜单()----关于菜单》http://blog.csdn.net/ljheee/article/details/52334997讲解了菜单相关的基本基础。这篇将讲解Android各种菜单的使用。

Android3.0 开始取消了实体的菜单按钮,引入了操作栏(Action Bar)。

Android5.0将操作栏更名为应用栏(App Bar),目前有以下四种形式的菜单:

•       选项菜单(Optionsmenu)

•       上下文菜单(Contextmenu)

•       上下文操作栏(ContextualAction Bar)

•       弹出菜单(Popupmenu)

一、    选项菜单(Options menu)

1、选项菜单(Options menu)的效果图如下:

Android----菜单的使用_第1张图片

2、选项菜单---类描述

属性

描述

Menu

menu

菜单(在其上添加菜单项,从其中获取菜单项)

MenuItem

item

菜单项(实际点击的控件)

SubMenu

menu

子菜单(只有一级)

group

菜单项可编组,设置 id 标识,用于统一管理:单选、多选、是否可见及可用

MenuInflater

实例化 res/menu  中的文件为菜单对象

3、选项菜单---相关方法

  public boolean onCreateOptionsMenu(Menu menu):使用此方法调用OptionsMenu 。

  public boolean onOptionsItemSelected(MenuItemitem):选中菜单项后发生的动作。

  public void onOptionsMenuClosed(Menu menu):菜单关闭后发生的动作。

  public boolean onPrepareOptionsMenu(Menu menu):选项菜单显示之前onPrepareOptionsMenu方法会被调用,你可以用此方法来根据打当时的情况调整菜单。

  public boolean onMenuOpened(int featureId, Menumenu):单打开后发生的动作。

 

 4、本例通过定义XML文件、加载布局,演示选项菜单(Options menu)的使用。

(1)定义菜单布局文件

         在 res/menu 目录的 XML 文件中定义菜单项布局,各属性含义如下图:

Android----菜单的使用_第2张图片

选项菜单布局文件命名为main_opt_menu.xml,意为“主活动选项菜单”布局文件。代码如下:

xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@+id/action_about"
        android:title="About"
        app:showAsAction="always"/>

    <item android:id="@+id/action_setting"
        android:title="Setting"
        android:icon="@drawable/ic_setting_24dp"
        app:showAsAction="ifRoom"/>

    <item android:id="@+id/action_sort"
        android:title="Sort"
        android:icon="@drawable/ic_sort"
        app:showAsAction="always">
        
        <menu>
            <group
                android:id="@+id/group_sort"
                android:checkableBehavior="single">
                <item android:id="@+id/action_sort_size"
                    android:title="Size_sort"/>

                <item android:id="@+id/action_sort_time"
                    android:title="Time_sort"/>
                <item android:id="@+id/action_sort_type"
                    android:title="Type_sort" />
            group>
        menu>

    item>

menu>
      该选项菜单布局文件中,定义了About关于、Setting设置、Sort排序三个菜单项;其中Sort下有3个二级子菜单,并且都放在一个组中,选择模式设为单选android:checkableBehavior="single",即放在一个单选组中,事件响应处理的时候,只可单选。Item的showAsAction:ifRoom(如果有空间则显示)或always(总是显示在操作栏)。

(2)加载菜单布局文件、创建菜单

 在主活动MainActivity类中,重写onCreateOptionsMenu(Menu menu)方法。
/**
 * 创建可选菜单
 * @param menu
 * @return
 */
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    //加载[选项菜单的]布局文件
    getMenuInflater().inflate(R.menu.main_opt_menu, menu);

    return true;
}
getMenuInflater().inflate(R.menu.main_opt_menu, menu);方法可加载到我们第一步创建的菜单布局文件main_opt_menu.xml,将会创建一个布局文件中指定的菜单[项]。

(3)菜单预处理方法

boolean isShowSort = true;
    /**
     * 预处理
     * 设置某些菜单项的属性:可见性,是否可选中
     * @param menu
     * @return
     */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {

//        menu.findItem(R.id.action_about).setVisible(false);
        menu.findItem(R.id.action_about).setVisible(isShowSort);

        return super.onPrepareOptionsMenu(menu);
    }
通过重写onPrepareOptionsMenu(Menu menu):选项菜单显示之前该方法会被调用,可以预处理某些菜单项是否显示和是否可操作。

(4)菜单项事件处理

/**
 * 选中菜单项(点击操作栏按钮)
 * @param item
 * @return
 */
@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if(item.getGroupId() == R.id.group_sort){
        //单选--排序组
        item.setChecked(true);
    }

    switch (item.getItemId()){
        case R.id.action_add:
            Toast.makeText(MainActivity.this,"Add",Toast.LENGTH_SHORT).show();//显示一条提示信息
            break;
        case R.id.action_search:

            break;

        default:break;
    }
    return true;
}
onOptionsItemSelected(MenuItem item)方法也是只需要在在主活动MainActivity类中重写,实现自己的处理即可。

二、    上下文菜单(Context menu)

1、上下文菜单(Context menu)的效果图如下:

Android----菜单的使用_第3张图片

        Android 的上下文菜单类似于 PC 上的右键菜单。当为一个视图注册了上下文菜单之后,长按(2 秒左右)这个视图对象就会弹出一个浮动菜单,即上下文菜单。任何视图都可以注册上下文菜单,不过,最常见的是用于列表视图ListView的item。注意:Android 的上下文菜单不支持图标或快捷键,只能通过长按弹出。上下文菜单很多时候回组合ListView使用。

 2、创建一个上下文菜单—步骤

(1)在Activity活动类创建时(onCreate()方法里),调用 registerForContextMenu() 方法,为视图注册上下文菜单。

(2)重写 Activity 的onCreateContenxtMenu() 方法,调用 Menu 的 add 方法添加菜单项(MenuItem)。

(3)重写 Activity 的onContextItemSelected() 方法,响应上下文菜单菜单项的选中事件。

Android----菜单的使用_第4张图片

3、源代码

(1)Activity活动类(ContextActivity.java)

package com.ljheee.menu.androidmenu;
import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;

/**
 * Activity
活动类
 
* 实现---上下文菜单
 
*/
public class ContextActivity extends Activity {

    //视图
   
private ListView listView;
    //数据
   
private List data = new ArrayList<>();
    //适配器
   
private ArrayAdapter adapter;

    private int position;

    @Override
   
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_context);

        for (int i = 0; i < 30; i++) {
            data.add("数据项 " + i);
        }

        listView = (ListView) findViewById(R.id.listView_cm);
        adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, data);
        listView.setAdapter(adapter);

        // 注册上下文菜单,调用onCreateContextMenu
       
registerForContextMenu(listView);

        // 注销上下文菜单
       
// unregisterForContextMenu(listView);
   
}

    /**
     *
创建上下文菜单
    
*
    * @param
menu    菜单
    
* @param
v       注册上下文菜单的视图
    
* @param
menuInfo 菜单信息
    
*/
   
@Override
   
public void onCreateContextMenu(ContextMenu menu,
                                    Viewv,
                                    ContextMenu.ContextMenuInfomenuInfo) {

        // 加载菜单文件
       
getMenuInflater().inflate(R.menu.menu_context, menu);

        // 设置菜单标题图标、标题文字
       
menu.setHeaderIcon(android.R.drawable.ic_menu_edit);
        menu.setHeaderTitle("操作");

        // 菜单信息:targetViewpositionid
       
AdapterContextMenuInfoinfo = (AdapterContextMenuInfo) menuInfo;

        // 列表中触发长按事件(弹出菜单)的位置
       
position = info.position;
    }

    /**
     *
选中菜单项
    
*
     * @param
item 被选中的菜单项
    
* @return 事件是否已处理完毕(消费)
    
*/
   
@Override
   
public boolean onContextItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case R.id.action_edit:
                doEdit();
                break;

            case R.id.action_copy:
                doCopy();
                break;

            case R.id.action_remove:
                doRemove();
                break;
        }
        return true;
    }

    @Override
   
public void onContextMenuClosed(Menu menu) {
        super.onContextMenuClosed(menu);
    }

    private void doRemove() {
        showToast("删除 " + data.get(position));
    }

    private void doCopy() {
        showToast("复制 " + data.get(position));
    }

    private void doEdit() {
        showToast("编辑 " + data.get(position));
    }

    private void showToast(String text) {
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
    }
}

(2)活动对应的布局文件activity_context.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:tools="http://schemas.android.com/tools"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
tools:context="com.newer.menu.ContextActivity"
>

    <ListView
       
android:id="@+id/listView_cm"
       
android:layout_width="match_parent"
       
android:layout_height="match_parent"
       
android:layout_alignParentLeft="true"
       
android:layout_alignParentStart="true"
       
android:layout_alignParentTop="true"
/>
RelativeLayout>

三、上下文操作栏(Contextual Action Bar)

1、上下文操作栏(Contextual Action Bar)的效果图如下:

 
  
                    
      和上下文菜单有些类似,只不过长按选项后,不是弹出浮动菜单,而是出现操作栏,如图。上下文操作栏不跟操作栏关联,它们独立地操作,上下文操作栏甚至可以显示在操作栏位置之上。当用户用长按事件选择一个项目时,系统会调用onCreateActionMode()方法,并显示带有特定操作的上下文操作栏。同时在上下文操作栏显示时,用户还能继续选择其他的项目,即多选。

2、相关方法

onCreateActionMode:上下文操作模式第一次被创建时调用。
onDestroyActionMode:当一个上下文操作模式被退出或销毁时调用。
onPrepareActionMode:当一个上下文操作模式的动作菜单无效时,将其重新刷新时调用。
onItemCheckedStateChanged :处于选择模式,一个选项被选择或取消选择时此方法被调用。
onActionItemClicked:用户点击一个动作按钮时调用。
这些都是回调方法,可以直接在Activity活动类中重写。
3、演示:针对ListView或GridView对象中项目组的批处理上下文操作(允许用户选择多个项目,并这些选择的项目上执行一个操作),比如图片、短信的多选删除,就是基于此。

4、源代码

(1)活动类CabActivity.java
package com.ljheee.menu.androidmenu;
import android.app.Activity;
import android.os.Bundle;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;

/**
 * 活动类
 * 演示---上下文操作栏(Contextual Action Bar)
 */
public class CabActivity extends Activity implements AbsListView.MultiChoiceModeListener {

    //视图
    private ListView listView;
    //数据
    private ArrayList data = new ArrayList();
    //适配器
    private ArrayAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cab);

        listView = (ListView) findViewById(R.id.listView_cab);
        initData();//初始化数据

        // 模版需要有选中状态(activated)
        adapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_activated_1,
                data);

        listView.setAdapter(adapter);

        // 设置选择模式
        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);

        // 设置多选监听器
        listView.setMultiChoiceModeListener(this);
    }

    private void initData() {
        for (int i = 0; i < 30; i++) {
            data.add("数据项 " + i);
        }
    }

    @Override
    public void onItemCheckedStateChanged(
            ActionMode mode,
            int position,
            long id,
            boolean checked) {

        // 获得选中的总数
        int count = listView.getCheckedItemCount();

        // 设置标题
        mode.setTitle(String.valueOf(count));
//        mode.setSubtitle();
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {

        // 创建菜单
        getMenuInflater().inflate(R.menu.menu_cab, menu);
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {

        switch (item.getItemId()) {
            case R.id.action_cab_copy:

                // 获得选中的多项【稀疏数组】
                SparseBooleanArray array = listView.getCheckedItemPositions();

                // 适用于有 ID 的数据
//                long[] ids = listView.getCheckedItemIds();

                break;
            case R.id.action_cab_remove:
                break;
        }

        // 结束 CAB 模式,调用 onDestroyActionMode 方法
        mode.finish();
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
    }
}
(2)活动类对应的布局文件activity_cab.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.newer.menu.CabActivity">


    <ListView
        android:id="@+id/listView_cab"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true" />
RelativeLayout>

四、弹出菜单(Popup menu)

1、弹出菜单---效果图

 
  
 
  
      弹出菜单比较简单,使用很灵活,在特定事件触发时,比如点击Button,执行一个响应方法,在这个方法里,就可动态创建菜单,并显示出来。

2、创建步骤

• 实例化 PopupMenu
• 加载菜单资源文件
• 设置菜单监听器
• 显示菜单

3、源代码

(1)活动类PopupActivity.java
package com.ljheee.menu.androidmenu;
import android.app.Activity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.PopupMenu;
/**
 * 活动类
 * 演示--弹出菜单
 */
public class PopupActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_popup);
    }

    public void onClick(View v) {

        // 创建弹出菜单
        // 参数一:上下文
        // 参数二:菜单的锚
        PopupMenu menu = new PopupMenu(this, v);

        // 加载菜单文件
        menu.inflate(R.menu.menu_popup);

        // 添加菜单项点击监听器
        menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                return true;
            }
        });

        // 添加菜单消失时的监听器【点击菜单项或其他区域,菜单会消失】
        menu.setOnDismissListener(new PopupMenu.OnDismissListener() {
            @Override
            public void onDismiss(PopupMenu menu) {

            }
        });

        // 显示菜单
        menu.show();
    }

}
(2)菜单资源布局文件menu_popup.xml(在res/menu文件夹下,右击res创建Menu)

<menu xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:tools="http://schemas.android.com/tools"
   
tools:context="com.newer.menu.PopupActivity"
>

    <item
       
android:id="@+id/action_pop_edit"
       
android:title="编辑"
/>

    <item
       
android:id="@+id/action_pop_remove"
       
android:title="删除"
/>

menu>

 完整工程:https://github.com/ljheee/AndroidMenu

你可能感兴趣的:(Android,Android开发)