Android Menu菜單使用

Android使用菜單使用

轉載自:http://blog.csdn.net/llping2011/article/details/11033031

    Android系統SDK對菜單提供了廣泛的支持,這裏我們介紹幾種常用的菜單:常規菜單、子菜單、上下文菜單、圖標菜單、輔助菜單和交替菜單。提供Android菜單支持的一個重要的類是Android.view.Menu,Android中每一個活動都與一個此類型的菜單對象相關聯,包括衆多的菜單項和子菜單。菜單項使用android.view.MenuItem表示,子菜單使用android.view.SubMenu表示。

   菜單項還具有名稱(標題)、菜單項ID、排序和ID,可以使用排序ID來指定菜單項在菜單中的順序,一些菜單排序數字範圍保留給了某些類型的菜單。如:

   容器菜單項以0x10000開始並由常量Menu.CATEGORY_CONTAINER定義。

   系統菜單項以0x20000開始並由常量Menu.CATEGORY_SYSTEM定義。

   輔助菜單項以0x30000開始並由常量Menu.CATEGORY_SECONDAR定義

   交替菜單項以0x40000開始並由常量Menu.CATEGORY_ALTERNATIVE定義

 

1)常規菜單

 

1.1、創建菜單   

   常規菜單是指當我們按下Menu的時候彈出的菜單。Android SDK中無需從頭開始創建菜單因爲一個活動只與一個菜單關聯,所以Android會爲該活動創建此菜單,然後將它傳遞給Activity類的onCreateOptionsMenu回調。

  1. <span style="font-family: KaiTi_GB2312; font-size: 14px;">  @Override  
  2.     public boolean onCreateOptionsMenu(Menu menu) {  
  3.         // TODO Auto-generated method stub  
  4.         super.onCreateOptionsMenu(menu);  
  5.         int groupId = 100;  
  6.         int itemId = 1;  
  7.         int orderId = 1;  
  8.         menu.add(groupId, itemId, orderId, "item1");  
  9.         menu.add(groupId, itemId+1, orderId+1, "item2");  
  10.         return true;  
  11.     }</span>  
<span style="font-family:KaiTi_GB2312;font-size:14px;">	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		super.onCreateOptionsMenu(menu);
		int groupId = 100;
		int itemId = 1;
		int orderId = 1;
		menu.add(groupId, itemId, orderId, "item1");
		menu.add(groupId, itemId+1, orderId+1, "item2");
		return true;
	}</span>


   注意:在onCreateOptionsMenu中需要調用此方法的基類實現,以便系統能夠使用系統菜單項填充菜單,爲了使這項系統菜單項與其他類型菜單分開,Android從0x20000開始添加它們。添加菜單項的方法爲 public MenuItem add(int groupId, int itemId, int order, CharSequence title)其中第一個參數表上組ID,第二個參數表示菜單項ID,在選擇該菜單項時會將它發送給回調函數,第三個參數表示排序ID。這幾個參數都是可選的,如果不希望指定任何ID,可以使用Menu.NONE。

最後一個參數是菜單項的名稱或標題,除了是自由文本,也可以是R.java常量文件使用字符串資源。

   最後這個方法應該返回true,使菜單可見。如果返回false那麼菜單項將不可見。

 

1.2、使用菜單組

   由於菜單項ID和排序ID與組ID是獨立的,那麼組有什麼用呢?Android提供了一些基於組IDandroid.view.Menu類方法,可以使用這些方法操作組中的菜單項:

   public void removeGroup(int groupId)  刪除給定組ID的所有菜單項

   public void setGroupCheckable(int group, boolean checkable, boolean exclusive)  設置在選中菜單項時在該菜單項中顯示一個勾選標記。如果設置了exclusive標記那麼只允許該組中的一個菜單項處於勾選狀態。

   public void setGroupVisible(int group, boolean visible)  顯示或隱藏給定組ID中所有item項

   public void setGroupEnabled(int group, boolean enable)   使能給定組ID中所有Item項

 

1.3、響應菜單項     

   Android中可以採用多種方式來響應菜單項單擊。可以使用Activity類的onOptionsItemSelected方法,也可是使用單獨的監聽器,或者使用Intent。

1)通過onOptionsItemSelected響應菜單項

  1. @Override  
  2. public boolean onOptionsItemSelected(MenuItem item) {  
  3.     // TODO Auto-generated method stub  
  4.     if(item.getItemId() == 1) {  
  5.         Toast.makeText(this, "Select Item 1", Toast.LENGTH_LONG).show();  
  6.     } else if(item.getItemId() == 2) {  
  7.         Toast.makeText(this, "Select Item 2", Toast.LENGTH_LONG).show();  
  8.     }  
  9.     return super.onContextItemSelected(item);  
  10. }  
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		if(item.getItemId() == 1) {
			Toast.makeText(this, "Select Item 1", Toast.LENGTH_LONG).show();
		} else if(item.getItemId() == 2) {
			Toast.makeText(this, "Select Item 2", Toast.LENGTH_LONG).show();
		}
		return super.onContextItemSelected(item);
	}

   這裏通過MenuItem的getItemId()方法來檢查菜單項的ID,然後執行相應操作。如果onOptionsItemSelected處理了一個菜單項,將返回true,此菜單項事件將不會再進一步傳播,對於onOptionsItemSelected未處理的菜單項,應該通過調用基類的方法來處理,默認返回false。

2)通過監聽器響應菜單項

  通過重寫onOptionsItemSelected來響應菜單,是提供性能的推薦方法,菜單項還支持註冊用作回調的監聽器。首先需要實現onMenuItemClickListener接口,然後獲取此實現的一個示例並傳遞給菜單項。當單機該菜單時調用onMenuItemClickListener接口的onMenuItemClick方法。

 

  1. <span style="font-family: KaiTi_GB2312; font-size: 14px;">item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {  
  2.               
  3.             @Override  
  4.             public boolean onMenuItemClick(MenuItem item) {  
  5.                 // TODO Auto-generated method stub  
  6.                 return false;  
  7.             }  
  8.         });</span>  
<span style="font-family:KaiTi_GB2312;font-size:14px;">item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
			
			@Override
			public boolean onMenuItemClick(MenuItem item) {
				// TODO Auto-generated method stub
				return false;
			}
		});</span>


注意:如果onMenuItemClick返回true,將不會執行任何其他回調,監聽器代碼的優先級高於onOptionsItemSelected

 

3)使用Intent響應菜單項

   也可以使用MenuItem的setIntent(intent)方法,將菜單項與Intent關聯。默認情況下菜單項沒有與之關聯的Intent,但是當Intent與菜單項關聯後,並且沒有其他方法處理菜單項時,默認將使用startActivity(intent)調用該intent。

 

2)圖標菜單

   Android中不僅支持文本,還支持將圖像或圖標作爲菜單內容。但是使用菜單項有些限制:不能將圖標用於展開菜單,圖標菜單不支持菜單勾選標記,如果圖標菜單項中的文本太長,將從一定數量的字符之後截斷。

   創建菜單項和創建基於文本的菜單項一樣,然後使用MenuItem類的setIcon()方法來設置圖像。

   MenuItem item = menu.add(base, base+1, base+1, "Item1");

   item.setIcon(R.drawable.img1);

 

3)子菜單

   Menu對象可以有多個SubMenu對象,每個SubMenu對象通過調用Menu.addSubMenu()方法被添加到Menu對象中。將菜單項添加到子菜單的方式與將菜單項添加到菜單的方式相同,因爲SubMenu是派生自Menu。但是不能向子菜單添加更多的子菜單。

  1. private void addSubMenu(Menu menu) {  
  2.     int base = Menu.FIRST + 1;  
  3.     SubMenu subMenu = menu.addSubMenu(base, base+1, Menu.NONE, "subMenu");  
  4.     subMenu.add(base, base+2, base+2, "sub item1");  
  5.     subMenu.add(base, base+3, base+3, "sub item2");  
  6.     subMenu.add(base, base+4, base+4, "sub item3");  
  7. }  
	private void addSubMenu(Menu menu) {
		int base = Menu.FIRST + 1;
		SubMenu subMenu = menu.addSubMenu(base, base+1, Menu.NONE, "subMenu");
		subMenu.add(base, base+2, base+2, "sub item1");
		subMenu.add(base, base+3, base+3, "sub item2");
		subMenu.add(base, base+4, base+4, "sub item3");
	}

 

4)上下文菜單

    Android中通過名爲長單擊的操作來支持上下文菜單,長單擊的意思是在Android視圖上按住的時間比平常稍微較長。上下文菜單被表示爲ContextMenu類,像Menu一樣,ContextMenu可以包含很多菜單項。活動只能擁有一個常規的視圖菜單,但可以用於多個上下文菜單。儘管上下文菜單歸視圖擁有,但是填充上下文菜單的方法包含在activity類中,爲activity.onCreateContextMenu()。

   注意:上下文菜單不支持快捷鍵、圖標和子菜單。

4.1、爲上下文菜單註冊視圖

  在活動的onCreate()方法中爲上下文菜單註冊視圖,在活動中調用registerForContextMenu(View v);

Demo:

  1. protected void onCreate(Bundle savedInstanceState) {  
  2.     super.onCreate(savedInstanceState);  
  3.     setContentView(R.layout.activity_main);  
  4.       
  5.     button = (Button) this.findViewById(R.id.btn);  
  6.     registerForContextMenu(button); // 註冊 長按彈出Menu列表  
  7. }  
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		button = (Button) this.findViewById(R.id.btn);
		registerForContextMenu(button);	// 註冊 長按彈出Menu列表
	}

 

4.2、填充上下文菜單  

   爲上下文菜單註冊了視圖之後,Android將使用此視圖作爲參數,調用onCreateContextMenu()方法,可以在該方法中爲上下文填充菜單項。

   public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)

   提供了三個參數,第一個參數是預先構造的ContextMenu對象,第二個參數是生成回調的視圖(如上面的Button),第三個參數是ContextMenuInfo類,這個是視圖向此方法傳遞附加信息的一種方式,視圖需要完成此操作需要重寫getContextMenuInfo()方法,並返回ContextMenuInfo的派生類。

  1. <span style="font-family: KaiTi_GB2312;">   @Override  
  2.     public void onCreateContextMenu(ContextMenu menu, View v,  
  3.             ContextMenuInfo menuInfo) {  
  4.         // TODO Auto-generated method stub  
  5.         if(v.getId() == R.id.btn) {  
  6.             menu.setHeaderTitle("這是一個ContextMenu");  
  7.             menu.add(3, 200, 200, "Context Menu 1");  
  8.             menu.add(3, 201, 201, "Context Menu 2");  
  9.         }  
  10.         super.onCreateContextMenu(menu, v, menuInfo);  
  11.     }</span>  
<span style="font-family:KaiTi_GB2312;">	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		// TODO Auto-generated method stub
		if(v.getId() == R.id.btn) {
			menu.setHeaderTitle("這是一個ContextMenu");
			menu.add(3, 200, 200, "Context Menu 1");
			menu.add(3, 201, 201, "Context Menu 2");
		}
		super.onCreateContextMenu(menu, v, menuInfo);
	}</span>


4.3、響應上下文菜單    

    實現上下文菜單的最後一步是響應上下文菜單單擊,響應上下文菜單的機制與響應選項菜單的機制類似,Android提供了一個onContextItemSelected方法。

  1. @Override  
  2. public boolean onContextItemSelected(MenuItem item) {  
  3.     // TODO Auto-generated method stub  
  4.     if(item.getItemId() == 200) {  
  5.         Toast.makeText(this, "Select Item 1", Toast.LENGTH_LONG).show();  
  6.     } else if(item.getItemId() == 201) {  
  7.         Toast.makeText(this, "Select Item 2", Toast.LENGTH_LONG).show();  
  8.     }  
  9.     return super.onContextItemSelected(item);  
  10. }  
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		if(item.getItemId() == 200) {
			Toast.makeText(this, "Select Item 1", Toast.LENGTH_LONG).show();
		} else if(item.getItemId() == 201) {
			Toast.makeText(this, "Select Item 2", Toast.LENGTH_LONG).show();
		}
		return super.onContextItemSelected(item);
	}

 

5)交替菜單

    交替菜單支持Android上的多個應用程序相互使用,這些交替菜單是Android應用程序間通信或使用框架的一部分。交替菜單允許一個應用程序包含另一個應用程序的菜單,當選擇交替菜單時,將使用該活動所需的數據URI啓動目標應用程序或活動。調用的活動使用傳入的Intent中的數據URI。

   要創建交替菜單項附加到菜單上,執行以下步驟,同時在onCreateOptionsMenu方法中設置該菜單

1、創建一個Intent,將它的數據URI設置爲當前顯示數據的URI。

2、將Intent的類別設置爲CATEGORY_ALTERNATIVE

3、搜索允許對此URI類型支持的數據進行操作的活動。

4、將可以調用這些活動的Intent以菜單項的形式添加到菜單。

   通過this.getIntent().getData()獲得可能在此活動上使用的數據的URI。然後找到使用此類數據的其他程序,我們使用一個Intent作爲參數來進行搜索:

   Intent criteriIntent = new Intent(null, getIntent().getData());

   intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

   現在我們可以告訴Menu對象搜索匹配活動,並將它們作爲菜單選項進行添加:

   menu.addIntentOptions(

       Menu.CATEGORY_ALTERNATIVE, // Group

       Menu.CATEGORY_ALTERNATIVE, // Id

       Menu.CATEGORY_ALTERNATIVE, // Order

       this.getComponentName(),  // Name of the activity class displaying

       null,  // No specific

       criteriIntent, // intent

       0,

       null

   );

  匹配活動是指能夠處理已爲他提供的URI的活動,活動通常會使用URI、操作和類別在其描述文件中註冊信息。Menu類的方法addIntentOptions負責查找與Intent的URI和類別特性匹配的活動,然後該方法使用合適的菜單項ID和排序ID,將這些活動添加到正確組下的菜單中。

 

使用菜單響應數據變化:

   到現在爲止我們用的都是靜態菜單,設置了菜單之後就不能根據屏幕內容改變菜單項。Android爲我們提供了onPrepareOptionsMenu方法來創建動態菜單,此方法類似於onCreateOptionsMenu,但每次調用菜單時都會調用它。

 

   

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