Android学习(一)菜单(Menus)

Android为我们提供了3中菜单:

    1. 选项菜单(Option Menu)
    2. 上下文菜单(Context Menu)
    3. 弹出菜单(Popup Menu)

选项菜单(Option Menu)

选项菜单就是当我们单击硬件设备上的菜单按钮而弹出的菜单(在android11(Android3.0)及以后版本通过ActionBars来实现,下面我们会讲到)

要构建选择菜单我们一般需要 重载 Activity的onCreateOptionsMenu(Menu menu)方法来创建选项菜单

  1. 通过硬编码来实现
  2. 通过资源文件来构建

下面我们分别通过实例来演示选项菜单的构建(注:以下实例都在Android4.1.2运行通过

首先我们构建一个Android项目:

1.File -–>New—>Project—>Android Application Project来构建一个Android Project

这里我命名为:AD_MenusDemo,入口Activity命名为MainActivity

我们的项目结构如下图所示:

image_thumb11

通过硬编码来实现

1.我们修改入口Activity对应的布局文件activity_main.xml,添加4个Button:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/byresourceButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_menusby_resources" />

    <Button
        android:id="@+id/bycodingButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_menusby_coding" />


    <Button
        android:id="@+id/contextMenuButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_contextmenu" />


    <Button
        android:id="@+id/popupMenuButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_popuptmenu" />

</LinearLayout>

2.我们添加3个Activity:MenuByCodingActivity、MenuByResourceActivity、ContextMenuActivity

image_thumb1

3.我们打开入口类:MainActivity,初始化Button如下:

package com.jeriffe.android.app;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.MenuInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.PopupMenu;

public class MainActivity extends Activity {

    public Button btnCreateByResource, btnCreateByCoding, btnPopupMenu,
            btnContextMenu;

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

        SetupViews();
    }

    private void SetupViews() {
        btnCreateByResource = (Button) findViewById(R.id.byresourceButton);
        btnCreateByResource.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,
                        MenuByResourceActivity.class);
                startActivity(intent);
            }
        });

        btnCreateByCoding = (Button) findViewById(R.id.bycodingButton);
        btnCreateByCoding.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,
                        MenuByCodingActivity.class);
                startActivity(intent);
            }
        });

        btnContextMenu = (Button) findViewById(R.id.contextMenuButton);
        btnContextMenu.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,
                        ContextMenuActivity.class);
                startActivity(intent);
            }
        });

        btnPopupMenu = (Button) findViewById(R.id.popupMenuButton);
        btnPopupMenu.setOnClickListener(new OnClickListener() {
            @SuppressLint("NewApi")
            public void onClick(View v) {
                PopupMenu popup = new PopupMenu(MainActivity.this, v);
                MenuInflater inflater = popup.getMenuInflater();
                inflater.inflate(R.menu.activity_menu_by_resource,
                        popup.getMenu());
                popup.show();
            }
        });
    }
}

4.我们编辑MenuByCodingActivity如下:

package com.jeriffe.android.app;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.SubMenu;

public class MenuByCodingActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_menu_by_coding);
        setTitle("硬编码构建菜单");
    }

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

        file.add(1, Menu.FIRST + 11, 0, "New");
        file.add(1, Menu.FIRST + 12, 1, "Open");
        file.add(1, Menu.FIRST + 13, 2, "Save");
        file.add(1, Menu.FIRST + 14, 3, "Exit");

        edit.add(2, Menu.FIRST + 11, 0, "Cut");
        edit.add(2, Menu.FIRST + 12, 1, "Copy");
        edit.add(2, Menu.FIRST + 13, 2, "Paste");

        help.add(3, Menu.FIRST + 21, 0, "About");
        help.add(3, Menu.FIRST + 22, 1, "Check Update");

        return true;
    }
}

5.运行程序,主界面如下图左一:

image_thumb5 image_thumb18image_thumb15image_thumb16image_thumb19

6.我们点击第二个Button(通过硬编码构建选项菜单)会看到如上图左边第二个,我们点击红色圈圈中的Action overflow会看到左3

点击File会看到左4,点击Edit会看到左5。

7.如果我们要实现单击某一个菜单项来触发事件如何操作?

这里也是so easy,我们只需重载onOptionsItemSelected(MenuItem item)方法即可。我们还可以实现菜单项,或者菜单组的单选设置,这里我们可以通过以下2格方法:

setCheckable(boolean checkable)

onOptionsItemSelected(MenuItem item)

代码如下:

public class MenuByCodingActivity extends Activity {

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

        file.add(1, Menu.FIRST + 11, 0, "New");
        file.add(1, Menu.FIRST + 12, 1, "Open");
        file.add(1, Menu.FIRST + 13, 2, "Save");
        file.add(1, Menu.FIRST + 14, 3, "Exit");

        MenuItem item = edit.add(2, Menu.FIRST + 11, 0, "Cut");
        /*
         * setCheckable (boolean checkable) :设置菜单项是否可以被勾选
         */
        item.setCheckable(true);
        edit.add(2, Menu.FIRST + 12, 1, "Copy");
        edit.add(2, Menu.FIRST + 13, 2, "Paste");
        /*
         * setGroupCheckable(int group, boolean checkable, boolean exclusive)
         * 设置group下的所有菜单项是否可以被勾选 如果第三个参数exclusive=true,则这格group下的菜单项将作为一组单选菜单项
         */
        edit.setGroupCheckable(2, true, false);

        help.add(3, Menu.FIRST + 21, 0, "About");
        help.add(3, Menu.FIRST + 22, 1, "Check Update");
        help.setGroupCheckable(3, true, true);

        return true;
    }

    @Override
    /*
     * 我们可以 重载onOptionsItemSelected方法来实现MenuItem单击事件处理,也可以通过实现监听器来操作
     */
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case Menu.FIRST:
            Toast.makeText(MenuByCodingActivity.this, "File 菜单被选择",
                    Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 10:
            Toast.makeText(MenuByCodingActivity.this, "Edit 菜单被选择",
                    Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 20:
            Toast.makeText(MenuByCodingActivity.this, "Help 菜单被选择",
                    Toast.LENGTH_LONG).show();
            break;
        case Menu.FIRST + 11:
            Toast.makeText(MenuByCodingActivity.this, "New 菜单被选择",
                    Toast.LENGTH_LONG).show();
            break;
        }
        return super.onOptionsItemSelected(item);
    }
}

运行程序如下所示:

image_thumb32image_thumb35image_thumb34

至此我们第一个MenuAppDemo--硬编码MenusDemo到此,结束。

通过资源文件来构建Menus

1.我们修改activity_menu_by_resource.xml(是MenuByResourceActivity对应的Menu资源文件)文件添加如上硬编码实现的菜单结构

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/fileItem1"       
        android:title="File">
        <menu>
            <group android:id="@+id/group1" >
                <item
                    android:id="@+id/fileitem2"
                    android:title="New"/>
                <item
                    android:id="@+id/fileitem3"
                    android:title="Open"/>
                <item
                    android:id="@+id/fileitem4"
                    android:title="Save"/>
                <item
                    android:id="@+id/fileitem5"
                    android:title="Exit"/>
            </group>
        </menu>
    </item>
    <item
        android:id="@+id/editItem1"
        android:title="Edit">
        <menu>
            <group android:id="@+id/group2" >
                <item
                    android:id="@+id/edititem2"
                    android:title="Cut"/>
                <item
                    android:id="@+id/edititem3"
                    android:title="Copy"/>
                <item
                    android:id="@+id/edititem4"
                    android:title="Paste"/>
            </group>
        </menu>
    </item>
    <item
        android:id="@+id/helpItem1"
        android:title="Help">
        <menu>
            <group android:id="@+id/group3" >
                <item
                    android:id="@+id/helpitem2"
                    android:title="About"/>
                <item
                    android:id="@+id/helpitem3"
                    android:title="Check Update"/>
            </group>
        </menu>
    </item>
    <item
        android:id="@+id/Item1"
        android:title="Menu1"/>
    <item
        android:id="@+id/Item2"
        android:title="Menu2"/>
    <item
        android:id="@+id/Item3"
        android:title="Menu3"/>
    <item
        android:id="@+id/Item4"
        android:title="Menu4"/>

</menu>

2.我们修改MenuByResourceActivity如下:

package com.jeriffe.android.app;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MenuByResourceActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_menu_by_resource);
        setTitle("资源文件构建菜单");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_menu_by_resource, menu);
        return true;
    }
}

运行程序,在主界面我们点击第一个Button,如下图左一红色圈圈中的Button,之后的操作和上边的示例:通过硬编码来实现一样。

image_thumb45image_thumb44image_thumb43image_thumb46

上下文菜单(Context Menu)

上下文菜单的实现也是很容易的:

构建菜单:重载Activity的onCreateContextMenu方法

注册菜单到指定的View:registerForContextMenu(View view)

重载Activity的onContextItemSelected(MenuItem item),如果我们要实现菜单项的单击事件处理

我们还是通过实例来看如何实现:

我们接着上边的Demo,我们这次只需修改ContextMenuActivity的代码即可

这里我们构建菜单还是上边的Menu资源文件

这里我们是把上下文菜单register到EditText

package com.jeriffe.android.app;

import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;

public class ContextMenuActivity extends Activity {
    private EditText et;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_context_menu);

        et = (EditText) findViewById(R.id.editText1);

        registerForContextMenu(et);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        getMenuInflater().inflate(R.menu.activity_menu_by_resource, menu);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        // 这里实现上下文菜单的菜单项单击事件处理
        return super.onContextItemSelected(item);
    }
}

运行程序,我们点击主界面的第三个Button,如上图左二,之后在EditView里长按鼠标左键,即可看到上下文菜单(如上图右二)。

至此我们的上下文菜单就已经构建完成。

弹出菜单(Popup Menu)

弹出菜单的实例代码在MainActivity里面,运行程序如上图的右一

 btnPopupMenu = (Button) findViewById(R.id.popupMenuButton);
        btnPopupMenu.setOnClickListener(new OnClickListener() {
            @SuppressLint("NewApi")
            public void onClick(View v) {
                PopupMenu popup = new PopupMenu(MainActivity.this, v);
                MenuInflater inflater = popup.getMenuInflater();
                inflater.inflate(R.menu.activity_menu_by_resource,
                        popup.getMenu());
                popup.show();
            }
        });

至此我们的3中菜单的演示就已经完成了。

***********************************************************

上边实例都是在Android4.1.2中运行演示;下面是我在不同的Android版本中,选项菜单的不同效果:

Android2.2 WVGA800,这里看到的菜单效果和我的手机(S5830)的效果是一致的。

image_thumb51

如果版本是SDK3.0或者SDK3.2(都是平板),那么效果也和SDK4.1.2大致一样。

如果我删除资源文件中的values-v11及values-v14文件(如下所示左一圈中的2个文件夹)SDK版本是4.1.2

如果AVD的Built-In为:WXGA720;那么运行效果如下中间的所示,由于没有Menu硬件按键,我们无法操作。

如果是AVD的Built-In为:WVGA800;那么运行效果如下右一所示,由于我们有Menu硬件按键,我们可以操作菜单,但是效果确实3.0以前的效果。

如果我们保留values-v11及values-v14中的任何一个,那么运行效果和前面讲解的演示效果是一样的。

image_thumb52image_thumb58image_thumb61

至于为什么不同版本的效果不同这个是Goolge更新导致:在Version11(SDK3.0)及以后的版本,Google正式宣布取消Android系统中MENU键的使用,也就是基于Android 3.0及以上系统的手机都应没有MENU这一固定按键。所以菜单会出现在界面的右上角,也就是Action Bar的Action overflow中。

我们删除的文件夹是对应V11和V14的,至于为什么删除掉这2个文件夹,效果会和Version11以下的效果一致,我也不是太别清除,还望高手指点

源码下载:https://files.cnblogs.com/jeriffe/AD_MenusDemo.rar

原文地址:https://www.cnblogs.com/jeriffe/p/2757272.html