Android 菜单:OptionsMenu,ContextMenu,PopupMenu

Menu的功能:给用户提供一个可以进行管理,设置,以及不常用功能的整理和集合;

Menu如何设置:采用XML可以实现(java代码也可以创建);

Menu由Activity来加载和显示的,需要重写Activity的方法;

Activity需要重写方法进行菜单加载,以及菜单点击的处理

菜单可以分为三类:

1,上下文菜单(ContextMenu):长按某一个View,出现的菜单,称为上下文菜单(只出现在屏幕中间),类似于Windows的右键菜单

2,OptionsMenu:在Activity标题栏中,显示的菜单

3,PopupMenu:Android3.0以后添加的心功能,用来改进上下文菜单的显示效果(可显示在任意位置);

OptionsMenu

OptionsMenu是由Activity来加载的,才可以显示在标题栏上,Activity需要重写onCreateOptionsMenu(Menu,Menu)方法,来设置Activity的菜单;

<?xml version="1.0" encoding="utf-8"?>
<!--需要在layout中创建menu文件夹,然后创建菜单文件,通过xml描述的菜单-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <!--名词:菜单(menu),菜单项(menu item)-->
    <item
        android:id="@+id/action_sets"
        android:title="设置"
        />
    <item
        android:id="@+id/action_help"
        android:title="help"
        />
</menu>

 

    /**
     * !!!这个OptionMenu的创建,只会调用一次
     * 当Activity启动之后,需要进行菜单的加载,
     * 如果是实现了这个方法,并且menu菜单中,添加了菜单项menu item
     * Activity将会自动的支持菜单的显示;
     * @param menu
     * @return true 菜单可以显示,false 菜单不会显示
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //1,加载菜单,使用MenuInflater来加载,对应Activity已经包含一个menuInflater对象,可以直接使用
        menuInflater = getMenuInflater();

        //解析menu菜单文件,并且自动的将菜单添加到指定的参数2菜单中
        menuInflater.inflate(R.menu.main_menu,menu);
        return true;
    }

    /**
     * 当OptionMenu被选中的时候,回调此方法
     * @param item
     * @return true-->代表当前的菜单点击处理,已经处理过了
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        //因为这个方法,所有菜单都公用,所以需要通过menu的id来进行区分
        switch (item.getItemId()){
            case R.id.action_sets:
                Toast.makeText(this,"action_sets",Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_help:
                Toast.makeText(this,"action_help",Toast.LENGTH_SHORT).show();
                break;
        }
        return true;
    }

1,程序中onCreateOptionsMenu(Menu menu)方法,Activity自身含有的方法,只要重写该方法,系统会自动完成点击的时间调用;

2,onOptionsItemSelected(MenuItem item)方法为菜单的点击事件

3,MenuItem需要设置Id,来进行点击的判断;

4,菜单项id的通用规则:以“action_”开头,后面附带功能表示的单词;

ContextMenu

1,通常上下文菜单通过手指长按才会显示;

2,弹出一个浮动在界面上方的类似于对话框性质的界面;

3,上下文菜单点击,同样会出发相应的操作;

4,上下文菜单通常都是和点击的条目相关

上下文菜单的特点:针对特定的内容,进行的菜单显示;不同的内容,显示出来的菜单项也不同;

上下文菜单的加载方式:

与OptionMenu类似,都是同时能过回调来设置菜单的;

使用XML描述菜单,通过MenuInflater来加载菜单;

上下文菜单的触发和现实的机制:通过控件的长按来完成的;ListView/GridView默认支持上下文菜单

onCreateContextMenu()方法,通过参数3ContextMenuInfo可以传递附加信息,例如ListView,可以确定当前选择的Item的位置

上下文菜单的注册:

registerForContextMenu(View)---->注册上下文菜单

unregisterForContextMenu(View)--->释放上下文菜单的注册

步骤:
1,注册View来显示ContextMenu
2,实现Activity onCreateContextMenu()就可以显示;
3,处理点击:
点击上下文的时候,通常只有在ListView或者GridView的时候,才能够获取MenuInfo,来判断长按的是哪一项;
对于普通的View而言,菜单无法获取选中的是哪个View,通常需要使用成员变量来实现内容的访问;
onContextItemSelected(MenuItem item)是上下文菜单的点击处理方法,ContextMenuInfo转换AdapterContextMenuInfo获取位置;
Android当中,关于时间的处理,凡是带有Boolean返回类型事件,都有一个含义,如果返回true,事件不会再继续执行
public class ContactActivity extends Activity {
    private ArrayAdapter<String> arrayAdapter;
    private List<String> items;
    private ListView lv;

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

        lv = (ListView) findViewById(R.id.lv);
        items = new LinkedList<String>();
        for (int i = 0; i <50 ; i++) {
            items.add("item"+i);
        }
        arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,items);
        lv.setAdapter(arrayAdapter);

        registerForContextMenu(lv);
    }

    @Override
    protected void onDestroy() {

        unregisterForContextMenu(lv);
        super.onDestroy();
    }

    /**
     * 每一个上下文菜单,需要显示的时候,这个方法,就会被调用;
     * @param menu ContextMenu和Menu类似,里面可以添加多个菜单项;
     * @param v 实际上就是被长按的那个控件,v不同导致菜单不一样;
     * @param menuInfo 菜单在创建的时候,附加的信息,只有在listView和GridView item长按的时候才有效
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.context_image_menu,menu);
    }

    /**
     * 类似于onOptionsItemSelected,都是菜单项,点击之后,回调此方法,进行菜单事件的处理
     * @param item
     * @return true-->当前菜单项的处理已经完成了,false-->让Activity自己来处理
     */
    @Override
    public boolean onContextItemSelected(MenuItem item) {

        //从ListView中,长按出发的上下文菜单,每一个Item都会包含一个叫做MenuIfo的数据,这个数据包含了长按menu的位置
        switch(item.getItemId()){
            case R.id.action_image_save:
                ContextMenu.ContextMenuInfo menuInfo = item.getMenuInfo();
                if(menuInfo!=null){
                    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
                    int position = info.position;
                    items.remove(position);
                    arrayAdapter.notifyDataSetChanged();
                }
                break;
            case R.id.action_image_large:
                ContextMenu.ContextMenuInfo menuInfo1 = item.getMenuInfo();
                if(menuInfo1!=null){
                    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo1;
                    int position = info.position;

                    Toast.makeText(this,""+position,Toast.LENGTH_SHORT).show();
                }
                break;
        }
        return true;
    }
}

PopupMenu

Android3.0以后提出,可以直接显示在制定空间上的菜单,不再需要长按,而是通过代码来指定显示的控件及其位置;

其特点:必须通过创建new PopupMenu(Context,View),第二个参数代表菜单以哪个控件为基准来显示;PopupMenu虽然可以通过setOnMenuItemClickListener来设置菜单的点击事件处理,但是,PopupMenu和ContextMenu一样,都需要获取当前点击位置的信息;

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/action_image_save"
        android:title="删除"
    />
    <item
        android:id="@+id/action_image_large"
        android:title="修改"
    />
</menu>

 

public class PopupMenuActivity extends Activity implements PopupMenu.OnMenuItemClickListener {

    /**
     * 用于显示的弹出菜单
     */
    private PopupMenu popupMenu;
    private MenuInflater menuInflater;

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

    /**
     * 显示PopupMenu
     * @param view
     */
    public void btnShowPopup(View view) {
        if(popupMenu==null){
            //创建PopupMenu,参数2:指定菜单与哪个控件挨着
            popupMenu = new PopupMenu(this,view);

            //设置菜单项,从xml加载
            //获取菜单加载器
            menuInflater = popupMenu.getMenuInflater();
            menuInflater.inflate(R.menu.context_image_menu,popupMenu.getMenu());

            popupMenu.setOnMenuItemClickListener(this);
        }
        //显示菜单
        popupMenu.show();
    }

    /**
     * 菜单项 点击的时候的调用
     * @param item
     * @return
     */
    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch(item.getItemId()){
            case R.id.action_image_save:
                Toast.makeText(this,"保存图片",Toast.LENGTH_SHORT).show();
                break;
        }
        return true;
    }
}
posted @ 2015-11-27 21:48  wmkill  阅读(2732)  评论(0编辑  收藏  举报