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();

                                               }

                                     });

 

                            }

                   });

         }

}

 

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