Android之三种Menu的使用

Posted sq19920518

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android之三种Menu的使用相关的知识,希望对你有一定的参考价值。

一、OptionMenu(选项菜单)

  当用户点击手机menu键会弹出菜单,菜单在2.3系统中最多显示6项如果超过在6项则显示一个More。4.0以后系统中会根据屏幕的高度决定菜单的项数。

1. 创建

  为 Activity 指定选项菜单,重写 onCreateOptionsMenu()(Fragment 对应 onCreateOptionsMenu() 回调)。启动 Activity 时会调用 onCreateOptionsMenu()方法,因此可以在该方法中将菜单资源(使用 XML 定义)注入到回调方法的Menu 中。 

几个方法介绍:
public boolean onCreateOptionsMenu(Menu menu):使用此方法调用OptionsMenu。
public boolean onOptionsItemSelected(MenuItem item):选中菜单项后发生的动作。
public void onOptionsMenuClosed(Menu menu):菜单关闭后发生的动作。  
public boolean onMenuOpened(int featureId, Menu menu):单打开后发生的动作。
public boolean onPrepareOptionsMenu(Menu menu):选项菜单显示之前onPrepareOptionsMenu方法
会被调用,你可以用此方法来根据当时的情况调整菜单。

2. 处理响应事件

  重写 onOptionsItemSelected() 方法,方法将传递所选中的 MenuItem。您可以通过调用 getItemId() 方法来识别对应item,该方法将返回菜单项的唯一 ID(由菜单资源中的 android:id 属性定义)。
  
案例演示一:

package com.vince.day10_optionsmenu;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends Activity 

    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.text);
    

    /**
     * 创建选项菜单
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.main, menu);
        menu.add(R.id.select_color, 1, 4, "灰色");
        return super.onCreateOptionsMenu(menu);
    

    /**
     * 处理菜单项的点击事件
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        switch (item.getItemId()) 
        case R.id.action_quit:
            finish();// 返回
            break;
        case R.id.select_color_blue:
            textView.setTextColor(Color.BLUE);
            break;
        case R.id.set_size_30:
            textView.setTextSize(20);
            break;
        default:
            break;
        
        return super.onOptionsItemSelected(item);
    

menu文件夹中的main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/action_quit"
        android:title="退出"/>
    <item android:id="@+id/select_color"
        android:title="选择颜色">
        <menu>
            <group >
                <item android:id="@+id/select_color_blue"
                    android:title="蓝色"/>
                <item android:id="@+id/select_color_red"
                    android:title="红色"/>
                <item android:id="@+id/select_color_green"
                    android:title="绿色"/>
            </group>
        </menu>
    </item>

    <item android:id="@+id/set_size"
        android:title="设置字体大小">
        <menu >
            <group >
                <item android:id="@+id/set_size_20"
                    android:title="20"/>
                <item android:id="@+id/set_size_30"
                    android:title="30"/>
                <item android:id="@+id/set_size_40"
                    android:title="40"/>
            </group>
        </menu>
    </item>
</menu>

效果图如下:

案例演示二:

package com.vince.optiondialog2;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends Activity 

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        /*
         * 
         * add()方法的四个参数,依次是:
         * 
         * 1、组别,如果不分组的话就写Menu.NONE,
         * 
         * 2、Id,这个很重要,Android根据这个Id来确定不同的菜单
         * 
         * 3、顺序,那个菜单现在在前面由这个参数的大小决定
         * 
         * 4、文本,菜单的显示文本
         */

        // setIcon()方法为菜单设置图标,这里使用的是系统自带的图标
        menu.add(menu.NONE, menu.FIRST + 1, 5, "删除").setIcon(
                android.R.drawable.ic_menu_delete);
        menu.add(menu.NONE, menu.FIRST + 2, 2, "保存").setIcon(
                android.R.drawable.ic_menu_save);
        menu.add(menu.NONE, menu.FIRST + 3, 6, "帮助").setIcon(
                android.R.drawable.ic_menu_help);
        menu.add(menu.NONE, menu.FIRST + 4, 1, "添加").setIcon(
                android.R.drawable.ic_menu_add);
        menu.add(menu.NONE, menu.FIRST + 5, 4, "详细").setIcon(
                android.R.drawable.ic_menu_info_details);
        menu.add(menu.NONE, menu.FIRST + 6, 3, "发送").setIcon(
                android.R.drawable.ic_menu_send);

        // 如果返回false,菜单则不会显示
        return true;

        // return super.onCreateOptionsMenu(menu);//效果等同上面
    

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        switch (item.getItemId()) 
        case Menu.FIRST + 1:
            Toast.makeText(this, "删除菜单被点击了", Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 2:
            Toast.makeText(this, "保存菜单被点击了", Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 3:
            Toast.makeText(this, "帮助菜单被点击了", Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 4:
            Toast.makeText(this, "添加菜单被点击了", Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 5:
            Toast.makeText(this, "详细菜单被点击了", Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 6:
            Toast.makeText(this, "发送菜单被点击了", Toast.LENGTH_LONG).show();
            break;
        default:
            break;
        

        return false;

        // return super.onOptionsItemSelected(item);//效果等同上面
    

    @Override
    public void onOptionsMenuClosed(Menu menu) 
        super.onOptionsMenuClosed(menu);
        Toast.makeText(this, "选项菜单关闭了", Toast.LENGTH_LONG).show();
    

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) 
        Toast.makeText(this,
                "选项菜单显示之前onPrepareOptionsMenu方法会被调用,
                你可以用此方法来根据当时的情况调整菜
                单",Toast.LENGTH_LONG).show();

        // 如果返回false,此方法就把用户点击menu的动作给消费了,onCreateOptionsMenu方法将不会被调用
        return true;
    

效果图如下:

二、ContexMenu(上下文菜单)

  用户长按某一控件时出现的浮动菜单,此菜单在屏幕顶部栏显示影响所选内容的操作项目,并允许用户选择多项,会直接影响对应的内容。上下文菜单是 ActionMode 的一种系统实现,它将用户交互的重点转到执行上下文操作上。
 
 案例演示: 

package com.danny_jiang.day10_contextmenu;

import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.view.ContextMenu.ContextMenuInfo;

/**
 * 上下文菜单
 * 与选项菜单最大的不同在于:
 *      上下文菜单属于Activity中的某一View
 *      需要长按某View之后,上下文菜单才会显示
 * 
 * 使用步骤:
 * 1 复写Activity的onCreateContextMenu方法,填充上下文菜单item
 * 2 通过registerForContextMenu方法将上下文菜单注册到某View控件上
 * 3 在onContextMenuSelected方法中拦截上下文菜单item的单击事件
 *
 */
public class MainActivity extends Activity 

    private TextView text;
    private ListView listView;

    private String[] data = new String[]"卡卡西", "路飞", "柯南";

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

        text = (TextView) findViewById(R.id.text);
        listView = (ListView) findViewById(R.id.list_Main);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
                android.R.layout.simple_list_item_1, data);
        listView.setAdapter(adapter);

        // 注册上下文菜单到View控件
        registerForContextMenu(text);
        registerForContextMenu(listView);
    

    /**
     * 创建上下文菜单内容
     * @param menu  所创建的菜单对象,需要将菜单item填充到此menu对象
     * @param menuInfo  
     *      是对上下文菜单的信息描述对象
     *      当拦截到上下文的单击事件时,可以通过此对象获取所点击item的信息
     *      如果此对象是AdapterContextMenuInfo,说明registerForContextMenu传入的参数是AdapterView
     *      
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) 
        super.onCreateContextMenu(menu, v, menuInfo);

        String title = null;
        /**
         * 如果注册的是AdapterView,需要将ContextMenuInfo强转成AdapterContextMenuInfo
         * 然后获取所长按的item位置position
         */
        if(menuInfo instanceof AdapterContextMenuInfo) 
            AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
            int position = adapterMenuInfo.position;
            title = data[position];
        else 
            title = "非AdapterView控件";
        

        // 设置上下文菜单的图标
        menu.setHeaderIcon(R.drawable.ic_launcher);
        // 设置上下文菜单的标题
        menu.setHeaderTitle("人物特征: " + title);
        getMenuInflater().inflate(R.menu.context_menu, menu);
    

    /**
     * 拦截上下文菜单item的单击事件
     */
    @Override
    public boolean onContextItemSelected(MenuItem item) 
        String title = item.getTitle().toString();
        switch (item.getItemId()) 
        case R.id.action_a:
            Toast.makeText(this, "点击了 " + title, Toast.LENGTH_SHORT).show();
            break;

        default:
            break;
        

        return super.onContextItemSelected(item);
    

activity_main.xml布局文件

<LinearLayout 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"
    android:orientation="vertical"
    tools:context="$relativePackage.$activityClass" >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <ListView
        android:id="@+id/list_Main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</LinearLayout>

context_menu.xml文件

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

    <item
        android:id="@+id/action_a"
        android:title="时间过得很快">
    </item>
    <item
        android:id="@+id/action_b"
        android:title="夜幕即将降临">
    </item>
    <item
        android:id="@+id/action_c"
        android:title="我觉得我必须要离开">
    </item>

</menu>

效果图如下:

  

考虑到篇幅原因,关于ActionMode的系统实现原理,不在此赘述,感兴趣可参考博客http://blog.csdn.net/evan_man/article/details/51685022

三、PopupMenu

  PopupMenu 是锚定到 View 的动态菜单。如果空间足够,它将显示在定位视图左下方,否则显示在其左上方。适用于提供与特定内容相关的大量操作,或者为命令的另一部分提供选项,不会直接影响对应的内容。
  




案例演示:

package com.danny_jiang.day10_popmenu;

import android.app.Activity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.TextView;

/**
 * PopMenu的使用步骤
 * 1 初始化PopMenu对象
 *      需要传入一个所依赖的View对象,当弹出菜单时,所依赖的位置对象
 * 2 PopMenu设置item单击事件
 * 3 调用PopMenu.show方法将其显示
 *
 */
public class MainActivity extends Activity implements OnClickListener 

    private TextView text;
    private Button btn;

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

        text = (TextView) findViewById(R.id.text);
        btn = (Button) findViewById(R.id.button);

        text.setOnClickListener(this);
        btn.setOnClickListener(this);
    

    /**
     * @param v 就是所点击的View控件
     */
    @Override
    public void onClick(View v) 
        showPopMenu(v);
    

    /**
     * 显示弹出式菜单:宽度、高度
     * 当点击宽度或者高度时,将所点击的View属性设置到Activity的Title中
     */
    private void showPopMenu(final View v) 
        // 创建PopMenu,并设置弹出菜单的item
        PopupMenu popMenu = new PopupMenu(this, v);
        popMenu.getMenuInflater().inflate(R.menu.pop_menu, popMenu.getMenu());
        // 设置点击事件
        popMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() 

            @Override
            public boolean onMenuItemClick(MenuItem item) 
                switch (item.getItemId()) 
                case R.id.width:
                    // 通过View.getWidth方法获取View控件的宽度
                    int width = v.getWidth();
                    // 通过Activity.setTitle方法,可以直接设置Activity的标题栏
                    setTitle(width + "");
                    break;
                case R.id.height:
                    int height = v.getHeight();
                    setTitle(height + "");
                    break;

                default:
                    break;
                
                return false;
            
        );

        // 显示弹出式菜单
        popMenu.show();

    

pop_menu.xml文件:

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

    <item
        android:id="@+id/width"
        android:title="宽度"/>
    <item
        android:id="@+id/height"
        android:title="高度"/>

</menu>

效果图如下:

参考博客:http://www.cnblogs.com/xiajf/p/4560831.html
http://blog.csdn.net/evan_man/article/details/51685022
转载请注明出处,谢谢!http://blog.csdn.net/sq19920518/article/details/52644310

以上是关于Android之三种Menu的使用的主要内容,如果未能解决你的问题,请参考以下文章

Android之三种Menu的使用与分析

android menu问题

(转载)Android之三种网络请求解析数据(最佳案例)

android中的菜单menu可以在屏幕上一直显示吗

菜单(Menu)的三中创建方式——Android开发之路2

Android 中选项菜单(Option menu)的用法