Android18--菜单

标签: Android

创建时间:2016-9-25 09:56:47
更新时间:2016-9-25 12:10:40


undefined

OptionMenu(选项菜单) #

选项菜单是Android中最常见的菜单,通过Menu键来调用。

通过在MainActivity里重写这两个方法即可实现菜单功能:

onCreateOptionsMenu(Menu menu) 创建菜单
onOptionsItemSelected(MenuItem item) 菜单选择回调事件

下面的几个方法是可选的:

onPrepareOptionsMenu(Menu menu) 菜单显示前会的回调
onMenuOpened(int featureId, Menu menu) 菜单打开后的回调
onOptionsMenuClosed(Menu menu) 菜单关闭时的回调

示例1:动态创建选项菜单:

package com.a52fhy.learnmenu;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    /**
     * 菜单组id常量
     */
    final private int groupid = 1;

    /**
     * 菜单选项id常量(item_id)
     */
    final private int RED = 1001;
    final private int GREEN = 1002;
    final private int ATY2 = 1100;

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

    /**
     * 创建菜单
     * @param menu
     * @return
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(groupid, RED ,1, "红色");//分别是组id,选项id,排序,菜单名称
        menu.add(groupid, GREEN ,1, "绿色");
        menu.add(groupid, ATY2 ,1, "新页面");
        return true;
    }

    /**
     * 菜单选择回调事件
     * @param item
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case RED:
                Toast.makeText(MainActivity.this, "你选择了红色", Toast.LENGTH_SHORT).show();
                break;
            case GREEN:
                Toast.makeText(MainActivity.this, "你选择了绿色", Toast.LENGTH_SHORT).show();
                break;
            case ATY2:
                startActivity(new Intent(MainActivity.this, Main2Activity.class));
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * 菜单关闭时的回调,可选
     * @param menu
     */
    @Override
    public void onOptionsMenuClosed(Menu menu) {
        Toast.makeText(MainActivity.this, "菜单已关闭", Toast.LENGTH_SHORT).show();
        super.onOptionsMenuClosed(menu);
    }

    /**
     * 菜单显示前会的回调,可选
     * @param menu
     * @return
     */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        Toast.makeText(MainActivity.this, "菜单即将显示", Toast.LENGTH_SHORT).show();
        return super.onPrepareOptionsMenu(menu);
    }

    /**
     * 菜单打开后的回调
     * @param featureId
     * @param menu
     * @return
     */
    @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        Toast.makeText(MainActivity.this, "菜单已打开", Toast.LENGTH_SHORT).show();
        return super.onMenuOpened(featureId, menu);
    }
}

代码里注释已经写的很清楚了。注意的是,我们使用MenuItem add(int groupId, int itemId, int order, CharSequence title)方法添加菜单,参数依次是组id,选项id,排序,菜单名称。使用item.getItemId()方法获取菜单选项id。

示例2:使用xml方法编写菜单:

  1. 需要准备菜单资源。res目录新建menu目录(如果不存在),新建menu.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_setting"
        android:icon="@mipmap/ic_launcher"
        android:title="设置"/>
    <item android:id="@+id/menu_help"
        android:title="帮助" />

    <item android:title="打开子菜单">
        <menu>
            <item android:id="@+id/subMenu1"
                android:title="子菜单1"/>
            <item android:id="@+id/subMenu2"
                android:title="子菜单2" />
        </menu>
    </item>
</menu>

主要标签是menuitemmenu表示一个菜单组,item表示菜单项。item里面如果嵌套了menu,则表示子菜单。应该给每个item菜单选项添加id。

这里使用xml文件实现了子菜单的定义。如果你想在Java代码中添加子菜单的话,可以调用addSubMenu()方法。比如:

SubMenu file = menu.addSubMenu("文件");

file还需要addItem()添加菜单项哦!

  1. 实现菜单:
package com.a52fhy.learnmenu;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

public class Main2Activity extends AppCompatActivity {

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

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.menu_setting:
                Toast.makeText(Main2Activity.this, "设置", Toast.LENGTH_SHORT).show();
                break;
            case R.id.menu_help:
                Toast.makeText(Main2Activity.this, "帮助", Toast.LENGTH_SHORT).show();
                break;
            case R.id.subMenu1:
                Toast.makeText(Main2Activity.this, "子菜单1", Toast.LENGTH_SHORT).show();
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}

创建菜单的主要方法代码是:

MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);

inflater.inflate接收一个菜单资源id和一个menu对象。

ContextMenu(上下文菜单) #

上下文菜单是通过长按某个视图元素来弹出的。实现也很简单:

1) 使用`registerForContextMenu(View view)`注册上下文菜单;
2) 重写`onCreateContextMenu()`方法
3) 重写`onContextItemSelected()`方法为菜单项指定事件监听器

重要的方法:

onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) 创建菜单
onContextItemSelected(MenuItem item) 菜单选择回调事件

我们准备了id名为tv1TextView,通过长按弹出菜单。

package com.a52fhy.learnmenu;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

public class Main2Activity extends AppCompatActivity {

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

        //注册上下文为菜单
        registerForContextMenu(findViewById(R.id.tv1));
    }

    /**
     * 创建上下文菜单
     * @param menu
     * @param v
     * @param menuInfo
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        //MenuInflater inflater = getMenuInflater();
        MenuInflater inflater = new MenuInflater(this); //这样也可以获取inflater实例
        
        //设置标题,可选
        menu.setHeaderTitle("操作");
        
        inflater.inflate(R.menu.menu_context, menu);
        super.onCreateContextMenu(menu, v, menuInfo);
    }

    /**
     * 上下文菜单选项选中的回调
     * @param item
     * @return
     */
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.menu_setting:
                Toast.makeText(Main2Activity.this, "设置", Toast.LENGTH_SHORT).show();
                break;
            case R.id.menu_help:
                Toast.makeText(Main2Activity.this, "帮助", Toast.LENGTH_SHORT).show();
                break;
            case R.id.subMenu1:
                Toast.makeText(Main2Activity.this, "子菜单1", Toast.LENGTH_SHORT).show();
                break;
        }
        return super.onContextItemSelected(item);
    }
}

发现和选项菜单没啥区别,回调方法里的代码是一样的。多了个注册上下文菜单的步骤。

注意的是,和子菜单一样,上下文菜单都无法显示图标。

PopupMenu(弹出式菜单) #

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

pop_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/popMenu1"
        android:title="菜单1"/>
    <item android:id="@+id/popMenu2"
        android:title="菜单2" />
</menu>

实现菜单很简单,只需要为屏幕里的某个控件设置个点击事件的回调即可:

findViewById(R.id.tv2).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //新建实例
        PopupMenu popup = new PopupMenu(Main2Activity.this, v);

        //解析菜单资源
        popup.getMenuInflater().inflate(R.menu.pop_menu, popup.getMenu());

        //设置菜单点击的回调
        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()){
                    case R.id.popMenu1:
                        Toast.makeText(Main2Activity.this, "菜单1", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.popMenu2:
                        Toast.makeText(Main2Activity.this, "菜单2", Toast.LENGTH_SHORT).show();
                        break;
                }
                return true;
            }
        });
        popup.show();
    }
});
Build by Loppo 0.6.6