Android中Menu 菜单的使用

1.1    Menu 菜单

Menu 菜单

1.      OptionsMenu 选项菜单

特点:  当通过点击menu键或者3.0以上的手机上,点击右上方的三个点,出现的列表,都是有OptionMenu对象进行控制

2.      ContextMenu上下文菜单

特点:当长按指定控件后,在屏幕中心弹出列表对话框

3.      PopupMenu  浮动菜单

特点:通过指定控件指定监听,触发显示,可以让菜单列表显示在指定控件的下方

 

1.1.1  概述

菜单是一种非常常见的与用户交互的一种用户界面组件

从Android 3.0开始,Android不要求手机设备上必须提供MENU按键。因此Android推荐使用ActionBar来代替Menu

1.1.2  菜单的创建

1、通过代码创建

2、使用xml资源文件创建菜单(res/menu目录下)(建议使用,重点掌握)

 

1.1.3  菜单的分类

Options Menu         选项菜单

Context Menu         上下文菜单

Popup Menu  浮动菜单

 

1.1.4  在XML中定义Menu文件

位置:res/menu目录下

<menu>:代表菜单资源

<item>:菜单项

         android:id  // 菜单项的id

         android:icon  // 菜单项的图标

         android:title  // 菜单项的标题

         android:orderInCategory // 排序

         android:showAsAction // 在ActionBar上的显示参数(API 11)

                   never:不将MenuItem显示在ActionBar上(是默认值)

                   always:总是将该MenuItem显示在ActionBar上

                   ifRoom:当AcitonBar上有空间时将该MenuItem显示在ActionBar上,没有空间就放入溢出菜单中

                   withText:将该MenuItem显示在ActionBar上,并显示该菜单项的文本

                   显示自定义ActionBar的View,需要和actionViewClass这组参数结合使用(API14)

<group>:菜单组

二级菜单(子菜单的创建)

         概念:在menu Item中嵌套menu元素,可以实现多级菜单,嵌套的菜单叫做子菜单,一般只会使用二级菜单,如果菜单层次太深,会严重影响用户体验。

         二级可选菜单

                   android:checkableBehavior

                   有三个属性值可选

                            all(多选)

                            single(单选)

                            none(不可选)

1.1.5  选项菜单

使用步骤

         初始化选项菜单:onCreateOptionsMenu(Menu menu)

         为菜单项设置监听器:onOptionsItemSelected(MenuItem item)

OptionsMenu的使用方式:

方式一:纯代码处理(官方并不是特别推荐)

 

方式二:xml文件+代码(官方推荐方式)

 

 通过xml文件+代码实现Options Menu的显示

Xml文件:负责设置菜单列表中总共要显示哪些数据选项,以及这些选项的显示特点

 

代码: 负责处理加载xml文件,并处理点击事件

 

关于xml文件的处理:

1.      在res文件夹内容准备一个menu文件夹,所有控制菜单显示的xml文件均被存于此处

2.      在menu文件夹中创建一个xml文件,让该文件以menu标签作为根标签

3.      在menu标签之间添加item标签,每一个item标签代表一个菜单选项

4.      处理item标签中的属性

 

 

代码实现:

<?xml version="1.0"encoding="utf-8"?>

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

 

    <!--

    android:id 用于设置itemid,即唯一标识,用于稍后的点击判断

    android:title 用于设置标题

    android:orderInCategory 用于设置item选项在菜单列表中的排列顺序

    属性值越小,排列顺序越靠前,

    如果属性值相同,哪个item的代码在前面,哪个item就排名靠前

   

    android:icon 用于设置图标。注意:如果item是显示在菜单列表中,那么

    图标永远不显示

   

    android:showAsAction android3.0 以后才出的属性

    用于设置item在标题栏上的显示特点

    可选属性值:

    never  该选项永远显示在菜单列表中

    ifRoom 如果标题栏上有剩余空间,就显示在标题栏上,如果没有,就显示在菜单列表中

    always 该选项永远直接显示在标题栏上

    withText  让图标和文字同时显示

    -->

         <item

             android:id="@+id/item1"

             android:title="菜单项一"

            android:orderInCategory="3000"

            android:showAsAction="always|withText"

             android:icon="@drawable/ic_launcher"/>

         <item

             android:id="@+id/item2"

             android:title="菜单项二"

            android:orderInCategory="10"

            android:showAsAction="ifRoom"

             android:icon="@drawable/ic_launcher"/>

         <item

             android:id="@+id/item3"

            android:orderInCategory="20"

             android:title="菜单项三"

             android:icon="@drawable/ic_launcher"/>

</menu>

public class MainActivity extends Activity {

 

         @Override

         protected void onCreate(Bundle savedInstanceState) {

                   super.onCreate(savedInstanceState);

                   setContentView(R.layout.activity_main);

         }

         /*

          * 重写onCreateOptionsMenu方法,在此方法中加载xml文件参数:代表要显示的菜单对象

          *

          * 返回值:true 显示菜单, false 不显示菜单

          */

         @Override

         public boolean onCreateOptionsMenu(Menu menu){

                   // TODOAuto-generated method stub

                   /*

                    * my.xml文件中的所有item菜单选项添加到参数二指定的menu对象中显示

                    */

                   getMenuInflater().inflate(R.menu.my_menu, menu);

                   //通过代码添加菜单选项

                   /*

                    * 1. 该菜单选项所在组的groupId

                    * 2. 该菜单的唯一标识,id属性的值

                    * 3. 控制排列顺序,作用等同于orderInCategory属性

                    * 4:选项上要显示的文字标题

                    * */

                   menu.add(0, 1, 20, "代码添加menu");

                   return true;

         }

         //重写此方法,获取菜单项的点击事件,参数代表被点击的菜单选项

         @Override

         public boolean onOptionsItemSelected(MenuItemitem) {

                   // TODOAuto-generated method stub

                   Toast.makeText(this,item.getTitle()+String.valueOf(item.getItemId()), Toast.LENGTH_SHORT).show();

                   //区分被点击的item

                   switch (item.getItemId()){

                   caseR.id.item1:

                           

                            break;

                   caseR.id.item2:

                            break;

                   caseR.id.item3:

                            break;

                   }

                   return super.onOptionsItemSelected(item);

         }

}

 

1.1.5.1 示例代码

<?xml version="1.0"encoding="utf-8"?>

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

 

    <item

        android:id="@+id/menu1"

        android:orderInCategory="100"

        android:showAsAction="never"

        android:title="选项菜单1"/>

    <item

        android:id="@+id/menu2"

        android:orderInCategory="100"

        android:showAsAction="never"

        android:title="选项菜单2"/>

    <item

        android:id="@+id/menu3"

        android:orderInCategory="100"

        android:showAsAction="never"

        android:title="选项菜单3"/>

    <!--选项菜单可分组 -->

    <group android:id="@+id/menu_group1">

        <item

            android:id="@+id/menu4"

            android:orderInCategory="100"

            android:showAsAction="never"

            android:title="1选项菜单1"/>

        <item

            android:id="@+id/menu5"

            android:orderInCategory="100"

            android:showAsAction="never"

            android:title="1选项菜单2"/>

    </group>

    <!--XML添加具有子选项的菜单 -->

    <item

        android:id="@+id/con_son_menu"

        android:title="点击出子菜单">

        <menu>

            <!-- 样式出现选择样式 -->

            <group android:checkableBehavior="all" >

                <item

                                               android:checked="true"

                    android:id="@+id/con_son_menu_1"

                    android:title="子菜单1"/>

                <item

                    android:id="@+id/con_son_menu_2"

                    android:title="子菜单2"/>

            </group>

        </menu>

    </item>

 

</menu>

 

public class MainActivity extends Activity {

 

         @Override

         protected void onCreate(Bundle savedInstanceState) {

                   super.onCreate(savedInstanceState);

                   setContentView(R.layout.activity_main);

         }

        

         @Override

         public boolean onCreateOptionsMenu(Menu menu) {

                   // TODOAuto-generated method stub

                   //布局xml配置加载

                   getMenuInflater().inflate(R.menu.my_menu, menu);

                   //代码添加菜单项

                   menu.add(2, 2, 150, "2代码项1");

                   menu.add(2, 3, 150, "2代码项2");

                   /**

                    * 可以根据组ID决定组中的菜单项是否可见或可操作

                    */

                   menu.setGroupEnabled(2,false);

                   /**

                    * 通过代码添加有子菜单项的菜单

                    */

                   SubMenu sub = menu.addSubMenu(3, 33, 333, "代码子菜单");

                   sub.add(3, 34, 333, "1");

                   sub.add(3, 35, 333, "2").setOnMenuItemClickListener(new OnMenuItemClickListener() {

                           

                            @Override//boolean监听:代表处理完监听,是否还要进行额外操作

                            publicboolean onMenuItemClick(MenuItemitem) {

                                     // TODOAuto-generated method stub

                                     Toast.makeText(MainActivity.this, "=====+"+item.getTitle()+"设置单个子菜单事件", Toast.LENGTH_SHORT).show();

                                     returnfalse;

                            }

                   });

                   return true;

         }

        

         //菜单列表item的点击事件,参数代表被点击的item菜单选项

         @Override

         public boolean onOptionsItemSelected(MenuItem item) {

                   // TODOAuto-generated method stub

                   switch(item.getItemId()) {

                   case 34:

                            Toast.makeText(MainActivity.this, "点击了子菜单中的子选项1", Toast.LENGTH_SHORT).show();

                            break;

                   case 35:

                            Toast.makeText(MainActivity.this, "点击了子菜单中的子选项2", Toast.LENGTH_SHORT).show();

                            break;

                   }

                   return super.onOptionsItemSelected(item);

         }

}

1.1.6  上下文菜单

使用步骤

         初始化上下文菜单:onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo)

         为指定控件注册上下文菜单:registerForContextMenu(Viewview)

         为菜单项设置监听器:onContextItemSelected(MenuItemitem)

特点:当长按指定控件的时候显示的菜单列表

位置固定显示与屏幕中心

使用步骤:

大体步骤与OptionsMenu 基本一致

1.      通过menu文件夹中的xml文件定义菜单列表中要显示的内容

2.      重写onCreateContextMenu方法,在该方法中通过

3.      重写onContextItemSelected方法获取菜单选项被点击的监听事件

4.      在页面的onCreate方法中通过registerForContextMenu方法的参数指定长按哪个控件对象显示菜单

 

 

registerForContextMenu方法中传递的是一个listview对象时,ContextMenu是针对列表中每个item进行设置

在onContextItemSelected方法中可以通过以下方式获取别长按的item在listview中对应的position位置

//获取被点击的菜单选项对应的菜单信息封装对象

           AdapterContextMenuInfo aci = (AdapterContextMenuInfo) item.getMenuInfo();

           //通过菜单信息封装对象获取被点击的item的位置

           int position = aci.position;

1.1.6.1 示例代码

<?xml version="1.0"encoding="utf-8"?>

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

   

    <item

       android:id="@+id/list_item1"

       android:title="复制"/>

     <item

       android:id="@+id/list_item2"

       android:title="删除"/>

      <item

       android:id="@+id/list_item3"

       android:title="重命名"/>

 

</menu>

public class MainActivity extends Activity {

 

         private TextView tv;

         @Override

         protected voidonCreate(Bundle savedInstanceState) {

                   super.onCreate(savedInstanceState);

                   setContentView(R.layout.activity_main);

                   tv=(TextView) this.findViewById(R.id.tv);

                   registerForContextMenu(tv);

         }

 

         @Override

         public voidonCreateContextMenu(ContextMenu menu, View v,

                            ContextMenuInfomenuInfo) {

                   // TODO Auto-generated method stub

                   super.onCreateContextMenu(menu, v, menuInfo);

                   getMenuInflater().inflate(R.menu.main, menu);

         }

}

public class TwoActivity extends Activity {

         private ListView lv;

         ArrayList<String>list = newArrayList<String>();

         ArrayAdapter<String>adapter;

         @Override

         protected voidonCreate(Bundle savedInstanceState) {

                   // TODO Auto-generated method stub

                   super.onCreate(savedInstanceState);

                   setContentView(R.layout.activity_two);

                  

                   lv=(ListView) this.findViewById(R.id.listview1);

                   for(inti=0;i<10;i++){

                            list.add("item"+i);

                   }

                   adapter = newArrayAdapter<>(this,android.R.layout.simple_list_item_1, list);

                   lv.setAdapter(adapter);

                  

                   registerForContextMenu(lv);

         }

        

         @Override

         public voidonCreateContextMenu(ContextMenu menu, View v,  //v是传递过来的对象

                            ContextMenuInfomenuInfo) {

                   // TODO Auto-generated method stub

                   super.onCreateContextMenu(menu, v, menuInfo);

                   getMenuInflater().inflate(R.menu.list_menu, menu);

                  

                   v.setBackgroundColor(Color.RED);

         }

         @Override

         public booleanonContextItemSelected(MenuItem item) {

                   // TODO Auto-generated method stub

                   AdapterContextMenuInfoaci=(AdapterContextMenuInfo)item.getMenuInfo();

                   final intposition = aci.position;

                   switch (item.getItemId()) {

                   case R.id.list_item1//复制

                            list.add(list.get(position));

                            adapter.notifyDataSetChanged();

                            break;

                   case R.id.list_item2//删除

                            list.remove(position);

                            adapter.notifyDataSetChanged();

                            break;

                   case R.id.list_item3//重命名

                            Viewv = View.inflate(this,R.layout.custom, null);

                            final AlertDialog dialog = new AlertDialog.Builder(this)

                            .setView(v)

                            .show();

                            final EditText ed_name =(EditText)v.findViewById(R.id.ed_name);

                            Buttonbtn_ok = (Button) v.findViewById(R.id.btn_ok);

                            btn_ok.setOnClickListener(new OnClickListener() {

                                    

                                     @Override

                                     public voidonClick(View v) {

                                               // TODO Auto-generated method stub

                                               list.set(position, ed_name.getText().toString());

                                               adapter.notifyDataSetChanged();

                                               dialog.dismiss();

                                     }

                            });    

                            break;

                   }

                   return super.onContextItemSelected(item);

         }

         @Override

         public voidonContextMenuClosed(Menu menu) {

                   // TODO Auto-generated method stub

                   super.onContextMenuClosed(menu);

                   lv.setBackgroundColor(Color.WHITE);

         }

}

1.1.7  浮动菜单

使用步骤

         创建浮动菜单对象:PopupMenu popupMenu = newPopupMenu(this, btn_show_popupmenu);

                   参数1:上下文环境

                   参数2:需要绑定浮动菜单的控件id

         将菜单文件加载到内存中:getMenuInflater().inflate(R.menu.popup_menu,popupMenu.getMenu());

         为菜单项设置监听器:popupMenu.setOnMenuItemClickListener(OnMenuItemClickListener)

         显示菜单:popupMenu.show();

 

PopupMenu浮动菜单

特点:

1.      可以指定任意控件通过任意方式触发浮动菜单的显示

2.      可以显示在指定控件的下方

 

使用方式:

1.      获取控件对象,设置任意的监听,如设置tv的点击事件

代表是要在tv被点击时显示Popup Menu

//1.初始化popupmenu对象

                      /*

                       *  参数2:默认情况下是让pm稍后再显示的时候,可以显示在该控件的下方

                       *  但是当该控件下方没有足够的控件的时候,就让pm显示在该控件的上方

                       * */

                      PopupMenu pm = newPopupMenu(PopupMenuActivity.this,tv);

                      /*

                       * 3参的构造方法的参数3:用于指定pm与控件的对齐方式

                       * 此方法必须确保在 19版本,即4.4.2版本以上才能生效

                       * */

//                     PopupMenupm = new PopupMenu(PopupMenuActivity.this, tv, Gravity.RIGHT);

2.      向popupmenu对象中添加要显示的菜单选项

//添加方式一:

//                    getMenuInflater().inflate(R.menu.popup_menu,pm.getMenu());

                      //添加方式二

                      pm.inflate(R.menu.popup_menu);

3.      通过show方法显示popupmenu对象

pm.show();

设置popupmenu中菜单选项的点击事件:

//获取pm菜单选项的点击事件

                      pm.setOnMenuItemClickListener(new OnMenuItemClickListener() {

                           

                            @Override

                            public boolean onMenuItemClick(MenuItem item) {

                                  // TODO Auto-generated method stub

                                  Toast.makeText(PopupMenuActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();

                                  return false;

                            }

                      });

 

 

PopupWindow的使用:

浮动窗口, 特点:效果上是一个可以自定义显示及显示位置的对话框

 

使用方式:

//1.初始化对象

                      /*

                       * 1. 用于指定pw中要显示View对象

                       * 23. 用于指定pw显示时的宽高

                       * */

                      View vv= View.inflate(PopupWindowActivity.this, R.layout.custom, null);

                      PopupWindow pw = new PopupWindow(vv, 400, 400);

                     

                      //设置pw中的控件能够获取焦点

                      pw.setFocusable(true);

                     

                      //设置可以通过点击pw外部关闭pw,但是生效的前提

                      //是必须给pw设置了背景才行

                      //设置pw的默认背景,即如果custom布局中没有指定背景的话,就显示此背景

                      pw.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_launcher));

                      pw.setOutsideTouchable(true);

                     

                      //3.通过show**方法显示

//                    pw.showAsDropDown(tv,50, 50);

                      /*

                       * 1. 通过参数一指定的控件寻找该控件的父控件

                       * 以父控件的范围为基准

                       * 2. gravity 居中,右下等位置

                        * 34. 水平和垂直方向的偏移量

                       *

                       * */

                      pw.showAtLocation(tv, Gravity.CENTER, 0, 0);

 

 

1.1.8  扩展:PopupWindow(浮动窗口)

基本使用步骤

         构造方法:PopupWindow(View contentView, intwidth, int height)

                   参数1:contentView,浮动窗口中显示的内容

                   参数2:width,浮动窗口的宽度

                   参数3:height,浮动窗口的高度

         显示浮动窗口:showAsDropDown(Viewanchor, int xoff, int yoff)

                   参数1:anchor,浮动窗口出现在指定控件的下方

                   参数2:xoff,在X轴上的偏移量

                   参数3:yoff,在Y轴上的偏移量

         隐藏浮动窗口:dismiss()

显示带列表的浮动窗口

         创建ListView对象

                   setAdapter(ListAdapter):设置列表适配器,用于填充列表数据

                   setOnItemClickListener(OnItemClickListener):设置列表项的监听事件

         setFocusable(true):使浮动窗口可以获取焦点

         setBackgroundDrawable(newColorDrawable()):为解决焦点问题,这行代码必须执行

 

PopupWindow 补充:

当初始化PopupWindow对象时,需要通过构造方法传递PopupWindow要显示的宽高,除了直接指定宽高对应的数字之外,能不能设置成wrap_content或者match_parent??

解决方式:在需要指定宽高的位置,通过ViewGroup包内的LayoutParams的类中的静态常量即可调用FILL_PARENT,MATCH_PARENT和WRAP_CONTENT  属性设置了

 

 

1.1.8.1 示例代码

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

    xmlns:tools="http://schemas.android.com/tools"

    tools:context="com.example.day13popupmenu.popupwindow.MainActivity">

 

    <item

       android:id="@+id/pu_menu1"

       android:title="pm菜单1"/>

    <item

       android:id="@+id/pu_menu2"

       android:title="pm菜单2"/>

    <item

       android:id="@+id/pu_menu3"

       android:title="pm菜单3"/>

    <item

       android:id="@+id/pu_menu4"

       android:title="pm菜单4"/>

 

</menu>

public class MainActivity extends Activity {

        

         private TextView tv;

         @Override

         protected voidonCreate(Bundle savedInstanceState) {

                   super.onCreate(savedInstanceState);

                   setContentView(R.layout.activity_main);

                   tv =(TextView) this.findViewById(R.id.tv);

                  

                   tv.setOnClickListener(newOnClickListener() {

                           

                            @Override

                            public voidonClick(View v) {

                                     // TODO Auto-generated method stub

                                     PopupMenu pm = new PopupMenu(MainActivity.this, tv);

                                     getMenuInflater().inflate(R.menu.main,pm.getMenu());

                                     //pm.inflate(R.menu.main);

                                     pm.show();

                                     pm.setOnMenuItemClickListener(new OnMenuItemClickListener() {

                                              

                                               @Override

                                               public booleanonMenuItemClick(MenuItem item) {

                                                        // TODO Auto-generated method stub

                                                        Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();

                                                        return false;

                                               }

                                     });

                                     pm.setOnDismissListener(new OnDismissListener() {

                                              

                                              @Override

                                               public voidonDismiss(PopupMenu menu) {

                                                        // TODO Auto-generated method stub

                                                        Toast.makeText(MainActivity.this, "close",Toast.LENGTH_SHORT).show();

                                               }

                                     });

                            }

                   });

         }

 

}

 

public class TwoActivity extends Activity {

 

         private TextView tv;

 

         @Override

         protected voidonCreate(Bundle savedInstanceState) {

                   // TODO Auto-generated method stub

                   super.onCreate(savedInstanceState);

                   setContentView(R.layout.activity_main);

 

                   tv = (TextView) this.findViewById(R.id.tv);

                   tv.setOnClickListener(newOnClickListener() {

 

                            @Override

                            public voidonClick(View v) {

                                     View vv = View.inflate(TwoActivity.this, R.layout.custom,null);

                                     final PopupWindow pw = newPopupWindow(vv, 300, 300);

                                     // pw.showAsDropDown(vv,50,50);

                                      // 设置pw能够获得焦点

                                     pw.setFocusable(true);

                                     // 设置浮动窗体,点击旁白能够自动消失,但是必须要设置setBackgroundDrawable才能生效

                                     pw.setBackgroundDrawable(getResources().getDrawable(

                                                        R.drawable.ic_launcher));

                                     pw.setOutsideTouchable(true);

                                     pw.showAtLocation(vv,Gravity.CENTER, 0, 0);

 

                                     Buttonbtn_ok = (Button) vv.findViewById(R.id.btn_ok);

                                     final EditText ed_edit = (EditText) vv

                                                        .findViewById(R.id.ed_name);

                                     btn_ok.setOnClickListener(new OnClickListener() {

 

                                               @Override

                                               public voidonClick(View v) {

                                                        // TODO Auto-generated method stub

                                                        Toast.makeText(TwoActivity.this,

                                                                           ed_edit.getText().toString(),

                                                                           Toast.LENGTH_SHORT).show();

                                                        pw.dismiss();

                                               }

                                     });

 

                            }

                   });

         }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章