Android菜单的使用

1、Android菜单的使用

(在Android中总共有三种类型的菜单:选项菜单,子菜单,上下文菜单)
1.1、选项菜单(实现方式一)
(1)首先在src->menu->main.xml文件中创建菜单项。创建菜单项的标签是

   <menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.androidstudy.MainActivity" >    
    <!-- 在菜单中添加两个菜单项,使用android:id标签设置这个菜单项的唯一标识,使用android:title标签设置这个菜单项的内容 -->
    <!-- 使用android:icon来设置菜单中显示的图片 -->
    <item   
        android:id="@+id/menu_add"  
        android:title="Add"  
        android:icon="@android:drawable/ic_menu_add"/>  
     <item   
        android:id="@+id/menu_wallaper"  
        android:title="Wallpaper"  
        android:icon="@android:drawable/ic_menu_gallery"/>  
    <item   
        android:id="@+id/menu_search"  
        android:title="Search"  
        android:icon="@android:drawable/ic_search_category_default"/>  
    <item   
        android:id="@+id/menu_setting"  
        android:title="Settings"  
        android:icon="@android:drawable/ic_menu_preferences"/>  
</menu>  

(2)在需要使用菜单的Activity中重写两个方法:onCreateOptionsMenu()方法和onOpentionsItemSelected()方法:

/** 用于设置菜单是有显示,如果返回true则显示菜单,返回false不显示菜单
 说明:MenuInflater是用来实例化Menu目录下的Menu布局文件的,MenuInflater获取方法只有一种:Activity.getMenuInflater();其次,MenuInflater.inflater(int menuRes,Menumenu)(这里不代表inflater就是static方法,可以这样调用,只是为了描述方便)用来给当前活动创建菜单,inflate()方法接受两个参数,第一个参数用于指定我们通过那个资源文件来创建菜单,第二个参数用于指定我们的菜单项将被添加到那一个Menu对象中 */
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater mInflater = this.getMenuInflater();
        mInflater.inflate(R.menu.main, menu);
        setIconEnable(menu,true);
        return true;
    }
    /**
     * 菜单项被选中单击时触发该方法
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_add:
            Toast.makeText(this, "You Click one", Toast.LENGTH_SHORT).show();
            break;
        case R.id.menu_wallaper:
            Toast.makeText(this, "You Click two", Toast.LENGTH_SHORT).show();
            break;
        case R.id.menu_search:
            Toast.makeText(this, "You Click two", Toast.LENGTH_SHORT).show();
            break;
        case R.id.menu_setting:
            Toast.makeText(this, "You Click two", Toast.LENGTH_SHORT).show();
            break;
        }
        return true;
    }
    /**
     * 设置菜单中的图片是否显示
     * 在Android4.0系统中,创建菜单Menu,通过setIcon方法给菜单添加图标是无效的, 图标没有显出来,2.3系统中是可以显示出来的。这个问题的根本原因在于4.0系统中,涉及到菜单的源码类 MenuBuilder做了改变,mOptionalIconsVisible成员初始值默认为false,这就是为什么给菜单设置图标没有效果的原因;所以,只要我们在创建菜单时通过调用setOptionalIconsVisible方法设置mOptionalIconsVisible为true就可以了;这时候问题来了,要想调用该方法,就需要创建MenuBuilder对象,但是,我们是无法在开发的应用程序中创建MenuBuilder这个对象(MenuBuilder为系统内部的框架类)。这时候就需要考虑用反射了,在代码运行创建菜单的时候通过反射调用setOptionalIconsVisible 方法设置mOptionalIconsVisible为true,然后在给菜单添加Icon,这样就可以在菜单中显示添加的图标了
     * @param menu  需要显示图片的菜单对象
     * @param enable    设置是否显示图片
     */
    private void setIconEnable(Menu menu, boolean enable) {
        try {
            //通过类名得到这个类的Class对象,然后通过代表这个类的Class对象找到名为setOptionalIconsVisible的方法
            Class<?> clazz = Class
                    .forName("com.android.internal.view.menu.MenuBuilder");
            Method m = clazz.getDeclaredMethod("setOptionalIconsVisible",
                    boolean.class);
            m.setAccessible(true);
            // MenuBuilder实现Menu接口,创建菜单时,传进来的menu其实就是MenuBuilder对象(java的多态特征)
            m.invoke(menu, enable);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

这样就可以创建一个选项菜单,实现的效果如下:

这里写图片描述
(实现方式二:在Java代码中创建Menu,而不是用.xml文件)

public class BaseActivity2 extends Activity {
    // 点击菜单选项的常量Id
    private static final int menu1 = 1;
    private static final int menu2 = 2;
    private static final int menu3 = 3;
    private static final int menu4 = 4; 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_base);
    }

    // -------------------------------------------这部分为菜单选项----
    /**
     * ①:直接去覆盖public boolean onCreateOptionsMenu(Menu menu) { code......},
     * 这个方法,需要注意的是,这个方法如果覆盖的了,只会被创建一次,也就是说, 选项菜单只会去被实例化一次,,,之后就不会被去调用了
     * ②:调用Menu中的add()方法,来添加每一个菜单选项, add(groupId, itemId, order, titleRes)
     * group: 选项组号,一般都设置成0就OK啦 itenId: 选项的Id 很重要 order:顺序,一般来说都设置0就行了 titelRes:
     * 选项的标题名字 ③:当我们去点击某项的选项的时候,覆盖重写onOptionsItemSelected(MenuItem
     * item)这个方法去实现点击事件
     * @param group  : 选项组号,一般都设置成0就OK啦
     * @param itenId : 选项的Id 很重要
     * @param order  :顺序,一般来说都设置0就行了
     * @param titelRes   : 选项的标题名字   */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, menu1, 0, "Menu1").setIcon(android.R.drawable.ic_menu_add);
        menu.add(0, menu2, 0, "Menu2").setIcon(android.R.drawable.ic_menu_gallery);
        menu.add(0, menu3, 0, "Menu3").setIcon(android.R.drawable.ic_menu_search);
        menu.add(0, menu3, 0, "Menu3").setIcon(android.R.drawable.ic_menu_send);
        setIconEnable(menu, true);
        return true;
    }
    /**
     * 菜单项被选中单击时触发该方法
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {  
        case menu1:  
            Toast.makeText(this, "你点击Menu1", Toast.LENGTH_LONG).show();  
            break;  
        case menu2:  
            Toast.makeText(this, "你点击Menu2", Toast.LENGTH_LONG).show();  
            break;  
        case menu3:  
            Toast.makeText(this, "你点击Menu3", Toast.LENGTH_LONG).show();  
            break;  
        case menu4:  
            Toast.makeText(this, "你点击Menu4", Toast.LENGTH_LONG).show();  
            break;        
        }  
        return true;
    }

    /**
     * 设置菜单中的图片是否显示 在Android4.0系统中,创建菜单Menu,通过setIcon方法给菜单添加图标是无效的, 图标没有显出来,2.3系统中是可以显示出来的。这个问题的根本原因在于4.0系统中, 涉及到菜单的源码类 MenuBuilder做了改变,mOptionalIconsVisible成员初始值默认为false,这就是为什么给菜单设置图标没有效果的原因;所以,只要我们在创建菜单时通过调用setOptionalIconsVisible方法设置mOptionalIconsVisible为true就可以了; 这时候问题来了,要想调用该方法,就需要创建MenuBuilder对象,但是,我们是无法在开发的应用程序中创建MenuBuilder这个对象(MenuBuilder为系统内部的框架类)。这时候就需要考虑用反射了,在代码运行创建菜单的时候通过反射调用setOptionalIconsVisible方法设置mOptionalIconsVisible为true,然后在给菜单添加Icon,这样就可以在菜单中显示添加的图标了
     * @param menu : 需要显示图片的菜单对象
     * @param enable:  设置是否显示图片
     */
    private void setIconEnable(Menu menu, boolean enable) {
        try {
            // 通过类名得到这个类的Class对象,然后通过代表这个类的Class对象找到名为setOptionalIconsVisible的方法
            Class<?> clazz = Class                  .forName("com.android.internal.view.menu.MenuBuilder");
            Method m = clazz.getDeclaredMethod("setOptionalIconsVisible",
                    boolean.class);
            m.setAccessible(true);
            // MenuBuilder实现Menu接口,创建菜单时,传进来的menu其实就是MenuBuilder对象(java的多态特征)
            m.invoke(menu, enable);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

实现的效果同上面

1.2、子菜单

/*
 * SubMenu(子菜单)
 平时我们希望把同一类型的菜单进行分级来显示,这时候我们会用SubMenu.下面的Demo,是创建两个菜单选项,当点击Menu3的时候 会弹出menu1和menu2的菜单
 创建一个SubMenu的基本步骤如下: 
 ①: 先去覆盖Activity中的onCreateOptionsMenu()
 ②:调用addSubMenu()来添加子菜单项,然后调用add()来添加子菜单
 ③:覆盖onCreateOptionsMenu(Menu menu)menu.getItemId()来获取选项的Id,去响应单击事件
 * */
public class SubMenuActivity extends Activity {
    private static final int menu3 = 3;
    private static final int menu4 = 4;
    private static final int menu1 = 1;
    private static final int menu2 = 2;
     @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            // TODO Auto-generated method stub  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_base);  
        }     
        @Override  
        public boolean onCreateOptionsMenu(Menu menu) {  
            SubMenu M3 = menu.addSubMenu("Menu3");  
            MenuItem M4 = menu.add(0,menu4,0,"Menu4");  
            M3.add(0, menu1, 0, "Menu1").setIcon(android.R.drawable.ic_menu_add);  
            M3.add(0, menu2, 0, "Menu2").setIcon(android.R.drawable.ic_menu_search);  
            M4.setIcon(android.R.drawable.ic_menu_gallery);
            setIconEnable(menu, true);
            return true;  
        }     
        @Override  
        public boolean onOptionsItemSelected(MenuItem item) {  
            switch (item.getItemId()) {  
            case menu1:  
                Toast.makeText(this, "你点击的是Menu1", Toast.LENGTH_LONG).show();  
                break;  
            case menu2:  
                Toast.makeText(this, "你点击的是Menu2", Toast.LENGTH_LONG).show();  
                break;        
            case menu4:
                Toast.makeText(this, "你点击的是Menu4", Toast.LENGTH_SHORT).show();
                break;
            }  
            return true;  
        }       
        private void setIconEnable(Menu menu, boolean enable) {
            try {
                // 通过类名得到这个类的Class对象,然后通过代表这个类的Class对象找到名为setOptionalIconsVisible的方法
            Class<?> clazz = Class                      .forName("com.android.internal.view.menu.MenuBuilder");
                Method m = clazz.getDeclaredMethod("setOptionalIconsVisible",
                        boolean.class);
                m.setAccessible(true);
                // MenuBuilder实现Menu接口,创建菜单时,传进来的menu其实就是MenuBuilder对象(java的多态特征)
                m.invoke(menu, enable);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

运行结果:
这里写图片描述
这里写图片描述

1.3、上下文菜单

/*
 * ContexgMenu(上下文菜单)
   首先什么是上下文菜单,当我们长时间按住屏幕的时候,会弹出菜单,那个就是ContextMenu();
   看先文档中对创建ContextMenu()的方法:
  【注】 长按按钮,来显示上下文菜单我们必须要去调用  registerForContextMenu(View) ,onCreateContextMenu(ContextMenu, View, ContextMenu.ContextMenuInfo)
 * */
public class ContextMenuActivity extends Activity{
    private static final int menu1 = 1;  
    private static final int menu2 = 2;  
    private static final int menu3 = 3;    
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        // TODO Auto-generated method stub  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        //将指定的xml文件转换为View对象
        LayoutInflater layoutInf = this.getLayoutInflater();
        View view =  layoutInf.inflate(R.layout.activity_main, null);
        FrameLayout linearLayout = (FrameLayout)this.findViewById(R.id.container);      
        //为这个View注册上下文菜单
        registerForContextMenu(linearLayout);  
    }  

    @Override  
    public void onCreateContextMenu(ContextMenu menu, View v,  
            ContextMenuInfo menuInfo) {    
        super.onCreateContextMenu(menu, v, menuInfo);  
        menu.add(0, menu1, 0, "Menu1");  
        menu.add(0, menu2, 0, "Menu2");  
        menu.add(0, menu3, 0, "Menu3");  
    }    
    @Override  
    public boolean onContextItemSelected(MenuItem item) {  
        switch (item.getItemId()) {  
        case menu1:  
            Toast.makeText(this, "你 点击的是Menu1", Toast.LENGTH_LONG).show();              
            break;    
        case menu2:  
            Toast.makeText(this, "你点击的是Menu2", Toast.LENGTH_LONG).show();  
            break;  
        case menu3:  
            Toast.makeText(this, "你点击的是Menu3", Toast.LENGTH_LONG).show();  
            break;  
        }  
        return true;  
    }  

运行的效果:
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值