Android系列之UI組件----Menu菜單

Android系列之UI組件----Menu菜單

 

【聲明】html

歡迎轉載,但請保留文章原始出處→_→java

生命壹號:http://www.cnblogs.com/smyhvae/android

文章來源:http://www.cnblogs.com/smyhvae/p/4133292.html編程

 

【正文】app

從官方文檔瞭解到,從Android3.0(API level 11)開始,Android設備再也不要求提供一個專門的菜單按鈕,轉而推薦使用ActionBar。因此如今市面上不少新設備使用三個虛擬按鍵,並再也不額外提供菜單按鈕。ide

由於Android版本的發展,對於菜單的支持各個版本有很大的區別,而Android3.0是個分水嶺,大概能夠分爲下面三類:函數

  • OptionMenu和ActionBar:一些操做的集合,若是開發的平臺在Android3.0之上,推薦使用ActionBar,若是開發的平臺在Android2.3或之下,仍是可使用OptionMenu的。
  • ContextMenu和ActionMode:ContextMenu是一個浮動的窗口形式展示一個選項列表,ActionMode是一個顯示在屏幕頂部的操做欄,容許用戶選擇多個選項,ActionMode在Android3.0以後纔有支持。
  • Popup Menu:PopupMenu是固定在View上的模態菜單,以彈出的方式顯示,在Android3.0以後纔有支持。

【在XML中定義一個菜單】佈局

Android提供了標準的XML格式的資源文件來定義菜單項,而且對全部菜單類型都支持,推薦使用XML資源文件來定義菜單,以後再把它Inflater到Activity或者Fragment中,而不是在Activity中使用代碼聲明。post

而菜單的XML資源文件,須要建立在/res/menu/目錄下,而且包含一下幾個元素:this

  • <menu>:定義一個Menu,是一個菜單資源文件的根節點,裏面能夠包含一個或者多個<item>和<group>元素。
  • <item>:建立一個MenuItem,表明了菜單中一個選項。
  • <group>:對菜單項進行分組,能夠以組的形式操做菜單項。

<item>元素除了常規的id、icon、title屬性的支持,還有一個重要的屬性:android:showAsAction,這個屬性是起兼容性的,描述了在Android的高版本中,菜單項什麼時候以何種方式加入到ActionBar中。

<group>是對菜單進行分組,分組後的菜單顯示效果並無區別,惟一的區別在於能夠針對菜單組進行操做,這樣對於分類的菜單項,操做起來更方便,提供以下的操做:

  • Menu.setGroupCheckable():菜單組內的菜單是否均可選。
  • Menu.setGroupVisible():是否隱藏菜單組的全部菜單。
  • Menu.setGroupEnabled():菜單組的菜單是否有用。

若是菜單項須要單選或者多選,可使用android:checkableBehavior屬性設置,它能夠對單個<item>或者<group>設置一個組,這個屬性接受三個參數:single,單選;all,多選,none,沒有Checked的選項,默認。

當建立好一個XML菜單資源文件以後,可使用MenuInflater.inflate()方法填充菜單資源,使XML資源變成一個可編程的對象。

 

1、Options menu選項菜單:

OptionMenu,選項菜單,單擊手機上的菜單鍵(MENU)出現,必須設備具備菜單按鈕才能夠觸發。由於屏幕的限制,最多隻能展現六個菜單項,若是定義的菜單項超出了六個,其餘的菜單項將被隱藏,第六個菜單將會顯示「更多」,點擊展開更多的菜單。雖然說在Android3.0以後再也不推薦使用選項菜單,可是若是使用了,在Android3.0以後的設備上,選項菜單項將被默認轉移到ActionBar中,這個能夠經過android:showAsAction屬性控制。

建立選項菜單的核心步驟:

(1)重寫Activity的onCreateOptionMenu(Menu menu)方法,當菜單第一次被加載時調用

(2)調用Menu 的add( )方法添加菜單項(MenuItem),同時能夠調用MenuItem的setIcon()方法爲菜單項設置圖標(注:Android 3.0以後,即便添加了圖標也不會顯示)

(3)重寫Activity的OptionsItemSelected(MenuItem item)來響應菜單項(MenuItem)的點擊事件

來看一下具體的代碼實現:

新建Android工程MenuTest:

【方式一】經過配置文件添加Menu選項

(1)在res/menu/main.xml中定義菜單項。main.xml的代碼以下:

複製代碼
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.example.menutest.MainActivity" > <item android:id="@+id/start" android:orderInCategory="100" android:showAsAction="never" android:title="@string/start"/> <item android:id="@+id/over" android:orderInCategory="200" android:showAsAction="never" android:title="@string/over"/> </menu>
複製代碼

注:第9行和第15行的字符串引用,須要提早在strings.xml文件中設置好。

(2)MainActivity.java:

複製代碼
 1 package com.example.menutest;  2  3 import android.app.Activity;  4 import android.os.Bundle;  5 import android.view.Menu;  6 import android.view.MenuItem;  7 import android.widget.Toast;  8  9 10 public class MainActivity extends Activity { 11 12  @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15  setContentView(R.layout.activity_main); 16  } 17 18 19 //重寫onCreateOptionMenu(Menu menu)方法,當菜單第一次被加載時調用 20  @Override 21 public boolean onCreateOptionsMenu(Menu menu) { 22 // Inflate the menu; this adds items to the action bar if it is present. 23 //填充選項菜單(讀取XML文件、解析、加載到Menu組件上) 24  getMenuInflater().inflate(R.menu.main, menu); 25 return true; 26  } 27 28 //重寫OptionsItemSelected(MenuItem item)來響應菜單項(MenuItem)的點擊事件(根據id來區分是哪一個item) 29  @Override 30 public boolean onOptionsItemSelected(MenuItem item) { 31 // Handle action bar item clicks here. The action bar will 32 // automatically handle clicks on the Home/Up button, so long 33 // as you specify a parent activity in AndroidManifest.xml. 34 switch (item.getItemId()) { 35 case R.id.start: 36 Toast.makeText(this, "開始遊戲", Toast.LENGTH_SHORT).show(); 37 break; 38 case R.id.over: 39 Toast.makeText(this, "結束遊戲", Toast.LENGTH_SHORT).show(); 40 break; 41 42 default: 43 break; 44  } 45 return super.onOptionsItemSelected(item); 46  } 47 }
複製代碼

核心代碼是第24行:引用佈局文件menu.xml,而後在30行的方法中添加MenuItem的點擊事件。

運行程序,效果以下:

若是想讓MenuItem變成ActionBar的形式,能夠修改res/menu/main.xml中的android:showAsAction屬性,它的屬性值一共有下面幾種:

其中,ifRoom表示:若是有空間,就顯示出來。withText表示:只顯示文本(若是配了圖標的話)。若是將屬性設置爲always,效果以下:

若是須要添加子菜單,能夠修改menu.xml文件爲以下所示:

複製代碼
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.example.menutest.MainActivity" > <item android:id="@+id/start" android:orderInCategory="100" android:showAsAction="never" android:title="@string/start"/> <item android:id="@+id/over" android:orderInCategory="200" android:showAsAction="never" android:title="@string/over"/> <!-- 子菜單 --> <item android:id="@+id/setting" android:title="setting"> <menu> <item android:id="@+id/setting1" android:orderInCategory="300" android:showAsAction="never" android:title="聲音設置"/> <item android:id="@+id/setting2" android:orderInCategory="400" android:showAsAction="never" android:title="背景設置"/> </menu> </item> </menu>
複製代碼

因而,子菜單的點擊事件爲:

複製代碼
    public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. switch (item.getItemId()) { case R.id.start: Toast.makeText(this, "開始遊戲", Toast.LENGTH_SHORT).show(); break; case R.id.over: Toast.makeText(this, "結束遊戲", Toast.LENGTH_SHORT).show(); break; case R.id.setting1: Toast.makeText(this, "聲音設置", Toast.LENGTH_SHORT).show(); break; case R.id.setting2: Toast.makeText(this, "背景設置", Toast.LENGTH_SHORT).show(); break; default: break; } return super.onOptionsItemSelected(item); }
複製代碼

運行效果以下:

 

【方式二】經過Java代碼添加Menu選項:

固然了,上方的方式一是經過xml文件來添加Menu選項的,下面咱們經過Java代碼來添加Menu選項(此時已經不須要menu.xml文件了)。修改MainActivity.java,代碼以下: 

MainActivity.java:

複製代碼
 1 package com.example.menutest;  2  3 import android.app.Activity;  4 import android.os.Bundle;  5 import android.view.Menu;  6 import android.view.MenuItem;  7 import android.view.SubMenu;  8 import android.widget.Toast;  9 10 11 public class MainActivity extends Activity { 12 13 14 private static final int START_ITEM = Menu.FIRST; //Menu.FIRST的值就是1 15 private static final int OVER_ITEM = Menu.FIRST+1; 16 private static final int SET_ITEM1 = Menu.FIRST+2; 17 private static final int SET_ITEM2 = Menu.FIRST+3; 18 19 20  @Override 21 protected void onCreate(Bundle savedInstanceState) { 22 super.onCreate(savedInstanceState); 23  setContentView(R.layout.activity_main); 24  } 25 26 27 //重寫onCreateOptionMenu(Menu menu)方法,當菜單第一次被加載時調用 28  @Override 29 public boolean onCreateOptionsMenu(Menu menu) { 30 // Inflate the menu; this adds items to the action bar if it is present. 31 //填充選項菜單(讀取XML文件、解析、加載到Menu組件上) 32 // getMenuInflater().inflate(R.menu.main, menu); 33 34 //經過代碼的方式來添加Menu 35 //添加菜單項(組ID,菜單項ID,排序,標題) 36 menu.add(0, START_ITEM, 100, "Start"); 37 menu.add(0, OVER_ITEM, 200, "Over"); 38 //添加子菜單 39 SubMenu sub1 = menu.addSubMenu("setting"); 40 sub1.add(1, SET_ITEM1, 300, "聲音設置"); 41 sub1.add(1, SET_ITEM2, 400, "背景設置"); 42 43 return true; 44  } 45 46 //重寫OptionsItemSelected(MenuItem item)來響應菜單項(MenuItem)的點擊事件(根據id來區分是哪一個item) 47  @Override 48 public boolean onOptionsItemSelected(MenuItem item) { 49 // Handle action bar item clicks here. The action bar will 50 // automatically handle clicks on the Home/Up button, so long 51 // as you specify a parent activity in AndroidManifest.xml. 52 switch (item.getItemId()) { 53 case START_ITEM: 54 Toast.makeText(this, "開始遊戲", Toast.LENGTH_SHORT).show(); 55 break; 56 case OVER_ITEM: 57 Toast.makeText(this, "結束遊戲", Toast.LENGTH_SHORT).show(); 58 break; 59 60 case SET_ITEM1: 61 Toast.makeText(this, "聲音設置", Toast.LENGTH_SHORT).show(); 62 break; 63 64 case SET_ITEM2: 65 Toast.makeText(this, "背景設置", Toast.LENGTH_SHORT).show(); 66 break; 67 68 default: 69 break; 70  } 71 return super.onOptionsItemSelected(item); 72  } 73 }
複製代碼

注意第35行對各個參數的解釋。

運行程序,效果和上方gif圖的效果是同樣的。

總結:推薦用方式1來作。

 

2、Context menu:上下文菜單

顧名思義 與上下文(環境)有關。操做時須要長時間按住某個item不放,就會彈出Context menu。效果以下:

建立上下文菜單的核心步驟:

(1)覆蓋Activity的onCreateContextMenu(Menu menu)方法,調用Menu的add()方法添加菜單項(MenuItem)

(2)覆蓋Activity的onContextItemSelected(MenuItem iitem)來響應事件

(3)調用registerForContextMenu()方法來爲視圖註冊上下文菜單。

如今經過代碼來實現。

從新建一個Android工程MenuTest02,步驟以下:

咱們如今activity_main.xml中添加一個按鈕button1,代碼就不寫了。而後繼續:

(1)在res/menu/main.xml中定義菜單項。main.xml的代碼以下:

複製代碼
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.example.menutest02.MainActivity" > <item android:id="@+id/start" android:orderInCategory="100" android:showAsAction="never" android:title="@string/start"/> <item android:id="@+id/over" android:orderInCategory="200" android:showAsAction="never" android:title="@string/over"/> </menu>
複製代碼

(2)MainActivity.java:

複製代碼
 1 package com.example.menutest02;  2  3 import android.app.Activity;  4 import android.os.Bundle;  5 import android.view.ContextMenu;  6 import android.view.MenuItem;  7 import android.view.View;  8 import android.view.ContextMenu.ContextMenuInfo;  9 import android.widget.Button; 10 import android.widget.Toast; 11 12 13 public class MainActivity extends Activity { 14 15 private Button button1; 16  @Override 17 protected void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19  setContentView(R.layout.activity_main); 20 button1 = (Button)findViewById(R.id.button1); 21 //爲按鈕綁定上下文菜單(注意不是綁定監聽器) 22  registerForContextMenu(button1); 23  } 24 25 //建立上下文菜單 26  @Override 27 public void onCreateContextMenu(ContextMenu menu, View v, 28  ContextMenuInfo menuInfo) { 29 super.onCreateContextMenu(menu, v, menuInfo); 30 31  getMenuInflater().inflate(R.menu.main, menu); 32  } 33 34 //上下文菜單的觸發事件 35  @Override 36 public boolean onContextItemSelected(MenuItem item) { 37 switch (item.getItemId()) { 38 case R.id.start: 39 Toast.makeText(this, "開始···", Toast.LENGTH_SHORT).show(); 40 break; 41 42 case R.id.over: 43 Toast.makeText(this, "結束···", Toast.LENGTH_SHORT).show(); 44 break; 45 46 default: 47 break; 48  } 49 50 return super.onContextItemSelected(item); 51  } 52 53 }
複製代碼

核心代碼是第22行:爲按鈕button1綁定上下文菜單。注意不是綁定監聽器哦,不要一看到按鈕就綁定監聽器哈。

注:一個界面中只能有一個上下文菜單。

運行程序,長按button,效果以下:

注:若是是在java代碼中添加Menu,用參數menu來天添加就好了。

 

3、Popup menu:彈出式菜單

 PopupMenu,彈出菜單,一個模態形式展現的彈出風格的菜單,綁在在某個View上,通常出如今被綁定的View的下方(若是下方有空間)。

注意:彈出菜單是在API 11和更高版本上纔有效的。

核心步驟:

(1)經過PopupMenu的構造函數實例化一個PopupMenu對象,須要傳遞一個當前上下文對象以及綁定的View。

(2)調用PopupMenu.setOnMenuItemClickListener()設置一個PopupMenu選項的選中事件。

(3)使用MenuInflater.inflate()方法加載一個XML文件到PopupMenu.getMenu()中。

(4)在須要的時候調用PopupMenu.show()方法顯示。

如今經過代碼來實現。從新新建一個工程文件MenuTest03。步驟以下:

先在佈局文件activity_main.xml中加一個按鈕,代碼略。

(1)在res/menu/main.xml中定義菜單項。main.xml的代碼以下:

複製代碼
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.example.menutest03.MainActivity" > <item android:id="@+id/copy" android:orderInCategory="100" android:title="複製"/> <item android:id="@+id/delete" android:orderInCategory="100" android:title="粘貼"/> </menu>
複製代碼

(2)MainActivity.java:

複製代碼
 1 package com.example.menutest03;  2  3 import android.app.Activity;import android.os.Bundle;  4 import android.view.MenuInflater;  5 import android.view.MenuItem;  6 import android.view.View;  7 import android.view.View.OnClickListener;  8 import android.widget.Button;  9 import android.widget.PopupMenu; 10 import android.widget.PopupMenu.OnMenuItemClickListener; 11 import android.widget.Toast; 12 13 14 public class MainActivity extends Activity implements OnClickListener,OnMenuItemClickListener{ 15 16 17 private Button button1; 18  @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21  setContentView(R.layout.activity_main); 22 button1 = (Button)findViewById(R.id.button1); 23 button1.setOnClickListener(this); 24  } 25 26 //點擊按鈕後,加載彈出式菜單 27  @Override 28 public void onClick(View v) { 29 //建立彈出式菜單對象(最低版本11) 30 PopupMenu popup = new PopupMenu(this, v);//第二個參數是綁定的那個view 31 //獲取菜單填充器 32 MenuInflater inflater = popup.getMenuInflater(); 33 //填充菜單 34  inflater.inflate(R.menu.main, popup.getMenu()); 35 //綁定菜單項的點擊事件 36 popup.setOnMenuItemClickListener(this); 37 popup.show(); //這一行代碼不要忘記了 38 39  } 40 41 //彈出式菜單的單擊事件處理 42  @Override 43 public boolean onMenuItemClick(MenuItem item) { 44 // TODO Auto-generated method stub 45 switch (item.getItemId()) { 46 case R.id.copy: 47 Toast.makeText(this, "複製···", Toast.LENGTH_SHORT).show(); 48 break; 49 50 case R.id.delete: 51 Toast.makeText(this, "刪除···", Toast.LENGTH_SHORT).show(); 52 break; 53 default: 54 break; 55  } 56 return false; 57  } 58 59 }
複製代碼

注意14行代碼綁定了兩個監聽器:OnClickListener和OnMenuItemClickListener。 在綁定OnMenuItemClickListener監聽器時,選的是下面這個:

 

若是是在API 14及以上版本,32行34行能夠合併爲:popup.inflate(R.menu.main, popup.getMenu());

注意第37行代碼不要忘記show。

運行程序,單擊button,效果以下:

最後,附上整個文章的代碼:

【工程文件】

連接:http://pan.baidu.com/s/1eQ6EnUq 

密碼:438o

相關文章
相關標籤/搜索