欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android-UI开发之菜单

程序员文章站 2022-06-30 18:19:52
...

一.菜单Menu概述

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

二.选项菜单与子菜单

Android-UI开发之菜单

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开发之菜单

Android-UI开发之菜单

@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开发之菜单

1.上下文菜单概述

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

2.开发上下文菜单步骤

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

3.例子一

Android-UI开发之菜单
Android-UI开发之菜单

首先要在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目录下,根目录是
<item...>:定义菜单项
id、titleicon
checkable、checked、visible、enable

<group...>:将多个<item>包装成一个菜单组
checkableBehavior:none(不可选)all(多选)single(单选)
visible:指定该组是否可见
enable:指定该组是否可用
<item../>元素用于定义一份菜单项,<item../>元素又可包含<menu../>元素,位于<item../>元素内部的<menu../>就代表子菜单

(1).例子一

Android-UI开发之菜单

<?xml version="1.0" encoding="utf-8"?>
<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开发之菜单

<?xml version="1.0" encoding="utf-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 菜单