Android-UI开发之菜单

一.菜单Menu概述

  • OptionsMenu(选项菜单),默认看不到,当用户点击Menu键时,系统才显示应用关联的菜单。
    • SubMenu 子菜单
  • ContextMenu(上下文菜单),当用户一直按住某一个组件时,该组件关联的上下文菜单就显示出来。
  • PopupMenu(弹出式菜单),它会在指定组件上弹出PopupMenu,可以增加多个菜单项,并可以为菜单项增加子菜单。

二.选项菜单与子菜单

Android-UI开发之菜单_第1张图片

1.实现步骤

  • Menu菜单接口,SubMenu子菜单,MenuItem菜单项
  • add()方法用于添加菜单项
  • addSubMenu()用亍添加子菜单
  • 添加菜单或子菜单的步骤如下
    • 重写Activity的onCreateOptionsMenu(Menu menu)方法,在该方法里面调用Menu对象的方法来添加菜单项或子菜单
    • 如果希望应用程序能响应菜单项的单击事件,重写Activity的onOptionsItemSelected(MenuItem mi)方法

2.例子一

 public boolean onCreateOptionsMenu(Menu menu) {
        try {
            Class menuClass = Class.forName("com.android.internal.view.menu.MenuBuilder");
            Method menuMethod = menuClass.getDeclaredMethod("setOptionalIconsVisible", boolean.class);
            menuMethod.setAccessible(true);
            menuMethod.invoke(menu, true);
        }catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        MenuItem show_item = menu.add(0, Menu.FIRST, 0, "显示").setIcon(R.drawable.delete);
//      MenuItem share_item = menu.add(0, Menu.FIRST+1, 0, "分享");
        SubMenu shareMenu = menu.addSubMenu(0, Menu.FIRST+1, 0, "分享").setIcon(R.drawable.delete);
        shareMenu.setHeaderIcon(R.drawable.ic_launcher);
        shareMenu.setHeaderTitle("分享到...");
        shareMenu.add(0, 100, 0, "微信");
        shareMenu.add(0, 101, 0, "QQ");
        shareMenu.add(0, 102, 0, "新浪微博");


        MenuItem detail_item = menu.add(0, Menu.FIRST+2, 0, "详细");
        MenuItem delete_item = menu.add(0, Menu.FIRST+3, 0, "删除");
        MenuItem help_item = menu.add(0, Menu.FIRST+4, 0, "帮助");
        MenuItem save_item = menu.add(0, Menu.FIRST+5, 0, "保存").setIcon(R.drawable.circle);
        MenuItem other_item = menu.add(0, Menu.FIRST+6, 0, "其他");

        return true;
    }

Android-UI开发之菜单_第2张图片

Android-UI开发之菜单_第3张图片

@Override
    public boolean onOptionsItemSelected(MenuItem item) {//响应选项菜单的点击事件

        switch (item.getItemId()) {
        case Menu.FIRST:
            Toast.makeText(MainActivity.this,"你点击的是显示",Toast.LENGTH_SHORT).show();
            break;

        case 100:
            Toast.makeText(MainActivity.this,"你要分享到微信去",Toast.LENGTH_SHORT).show();
            break;
        }

        return true;
    }

3.注意事项

  • 超过6个MenuItem时,第6个显示为more,之后的以子菜单式样显示,不再显示图标
  • 通过addSubMenu()用亍添加子菜单
  • Menu可以包含多个SubMenu,SubMenu可以包含多个MenuItem
  • SubMenu不能包含SubMenu,子菜单不能嵌套
  • 子菜单可以添加菜单头标题、图标,但菜单项不能显示图标
  • 动态改变选项菜单的内容,需重写onPrepareOptionsMenu(Menu)

三.上下文菜单

Android-UI开发之菜单_第4张图片

1.上下文菜单概述

  • 类似于普通桌面程序的右键菜单
  • 点击界面元素超过2s后自劢出现的菜单
  • 可以被注册到任何View对象中(基本控件、布局文件、ListView的某一项等)

2.开发上下文菜单步骤

  • 重写Activity的onCreateContextMenu()方法
  • 调用Activity的registerForContextMenu(View view)方法为View组件组成上下文菜单
  • 重写onContextItemSelected(MenuItem m)方法为菜单项提供响应

3.例子一

Android-UI开发之菜单_第5张图片
Android-UI开发之菜单_第6张图片

首先要在xml中添加一个imageView,这个毫无疑问

重写onCreateContextMenu()

    private ImageView imageView;

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

        imageView=(ImageView) findViewById(R.id.imageView1);

        registerForContextMenu(imageView);//注册这个是必须的 如果不注册的话点击会没反应
    }
@Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {

        super.onCreateContextMenu(menu, v, menuInfo);

        switch (v.getId()) {

        case R.id.imageView1:

            menu.add(0,200,0,"QQ空间");
            menu.add(0,201,0,"微信");
            menu.add(0,202,0,"朋友圈");
            menu.add(0,203,0,"新浪微博");

            menu.setHeaderIcon(R.drawable.ic_launcher);
            menu.setHeaderTitle("分享到...");


            break;

        default:
            break;
        }
    }
 @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case 200:
            Toast.makeText(this,"你要分享到QQ空间去",Toast.LENGTH_SHORT).show();
            break;
        }
        return true;
    }

4.注意事项

  • 没有快捷键,不能显示菜单项图标
  • 每个Activity有且只有一个Options Menu,它为整个Activity服务
  • 上下文菜单的拥有者是Activity中的View,显示地通过registerForContextMenu(View view)来为View指定是否拥有上下文菜单,多个View都可拥有ContextMenu
  • onCreateOptionsMenu只在用户第一次按“Menu”键时被调用,而onCreateContextMenu会在用户每一次长按View时被调用
  • 视图元素需要向上下文菜单传递一些信息,比如该View对应DB记录的ID等,需要使ContextMenuInfo,并重写getContextMenuInfo()方法

5.使用XML文件定义菜单

  • 在res/menu目录下创建xxx.xml菜单布局文件
  • 定义菜单资源后,重写onCreateOptionsMenu()、onCreateContextMenu()方法
  • 在其中调用MenuInflater对象inflate方法装载指定资源的对应菜单xxx.xml
  • 好处
    • 简化Java代码,降低耦合
    • 为每个菜单项、菜单组分配ID,可扩展性强
  • 菜单资源文件放置在/res/menu目录下,根目录是
:定义菜单项
id、titleicon
checkable、checked、visible、enable

:将多个包装成一个菜单组
checkableBehavior:none(不可选)all(多选)single(单选)
visible:指定该组是否可见
enable:指定该组是否可用
<item../>元素用于定义一份菜单项,<item../>元素又可包含<menu../>元素,位于<item../>元素内部的<menu../>就代表子菜单

(1).例子一

Android-UI开发之菜单_第7张图片


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

    <item  
            android:id="@+id/mi_close"  
            android:icon="@drawable/ic_launcher" 
            android:title="Close"/>  

        <item  
            android:id="@+id/mi_no_icon"  
            android:title="Sans Icon"/>  

        <item  
            android:id="@+id/mi_disabled"  
            android:title="Disabled"/>  

        <item  
            android:id="@+id/mi_submenu"
            android:title="A Submenu" />  


menu>
 public boolean onCreateOptionsMenu(Menu menu) {
        try {
            Class menuClass = Class.forName("com.android.internal.view.menu.MenuBuilder");
            Method menuMethod = menuClass.getDeclaredMethod("setOptionalIconsVisible", boolean.class);
            menuMethod.setAccessible(true);
            menuMethod.invoke(menu, true);
        }catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        MenuInflater menuInflater=getMenuInflater();

        menuInflater.inflate(R.menu.mymenu, menu);

        return true;
    }
 @Override
    public boolean onOptionsItemSelected(MenuItem item) {//响应选项菜单的点击事件

        switch (item.getItemId()) {
        case R.id.mi_close:
            Toast.makeText(MainActivity.this, "你点击的是关闭", Toast.LENGTH_SHORT).show();
            break;

        case R.id.mi_disabled:
            Toast.makeText(MainActivity.this, "你点击的是Disabled", Toast.LENGTH_SHORT).show();
            break;
        }

        return true;
    }

6.Android4.0中setIcon无效的问题

  • 原因:菜单的源码类 MenuBuilder做了改变
public class MenuBuilder implements Menu {
...//mOptionalIconsVisible 为true时,才能显示图标
private boolean mOptionalIconsVisible = false;
....
 void setOptionalIconsVisible(boolean visible) {
 mOptionalIconsVisible = visible;
 }
 boolean getOptionalIconsVisible() {
 return mOptionalIconsVisible;
 }
...
}
  • 解决方法
    • 反射机制,在代码运行创建菜单的时候通过反射调用
//setOptionalIconsVisible方法设置mOptionalIconsVisible为true,然后在给菜单添加Icon即可生效
Class clazz =Class.forName("com.android.internal.view.menu.MenuBuilder");
Method m =clazz.getDeclaredMethod("setOptionalIconsVisible",boolean.class);
m.setAccessible(true);
m.invoke(menu, true); 

四.弹出式菜单PopupMenu

1.弹出式菜单概述

  • PopupMenu代表弹出菜单,它会在指定组件上弹出PopupMenu。需要在API 11以上的版本中才能使用
  • PopupMenu可以增加多个菜单项,可以为菜单项增加子菜单

2.创建PopupMenu步骤

  • 调用new PopupMenu(Context context,View anchor)创建下拉菜单,anchor代表要激发该弹出菜单的组件。
  • 调用MenuInflater的inflate()方法将菜单资源填充到PopupMenu中
  • 调用PopupMenu的show()方法显示弹出式菜单
  • 注意:PopupMenu的事件监听OnMenuItemClickListener

3.例子一

Android-UI开发之菜单_第8张图片


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

        <item  
            android:id="@+id/mi_qq"  
            android:icon="@drawable/ic_launcher"  
            android:title="QQ空间"/>  

        <item  
            android:id="@+id/mi_friend" 
            android:title="朋友圈"/>  

        <item  
            android:id="@+id/mi_tx"  
            android:enabled="true"  
            android:title="腾讯微博"/>  

        <item  
            android:id="@+id/mi_xl" 
            android:title="新浪微博"/>


menu>
button = (Button) findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                PopupMenu popupMenu = new PopupMenu(MenuActivity.this, button);
                popupMenu.getMenuInflater().inflate(R.menu.pop_menu, popupMenu.getMenu());
                popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {

                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        // TODO Auto-generated method stub
                        switch (item.getItemId()) {
                        case R.id.mi_qq:
                            Toast.makeText(MenuActivity.this, "你打算分享到QQ空间哇", Toast.LENGTH_SHORT).show();
                            break;

                        default:
                            break;
                        }
                        return true;
                    }
                });
                popupMenu.show();
            }
        });

END!!!!!!!!!

你可能感兴趣的:(android)