Android為我們提供了3中菜單:
- 選項菜單(Option Menu)
- 上下文菜單(Context Menu)
- 彈出菜單(Popup Menu)
選項菜單(Option Menu)
選項菜單就是當我們單擊硬件設備上的菜單按鈕而彈出的菜單(在android11(Android3.0)及以后版本通過ActionBars來實現,下面我們會講到)
要構建選擇菜單我們一般需要 重載 Activity的onCreateOptionsMenu(Menu menu)方法來創建選項菜單
- 通過硬編碼來實現
- 通過資源文件來構建
下面我們分別通過實例來演示選項菜單的構建(注:以下實例都在Android4.1.2運行通過)
首先我們構建一個Android項目:
1.File -–>New—>Project—>Android Application Project來構建一個Android Project
這里我命名為:AD_MenusDemo,入口Activity命名為MainActivity
我們的項目結構如下圖所示:
通過硬編碼來實現
1.我們修改入口Activity對應的布局文件activity_main.xml,添加4個Button:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/byresourceButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/btn_menusby_resources" /> <Button android:id="@+id/bycodingButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/btn_menusby_coding" /> <Button android:id="@+id/contextMenuButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/btn_contextmenu" /> <Button android:id="@+id/popupMenuButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/btn_popuptmenu" /> </LinearLayout>2.我們添加3個Activity:MenuByCodingActivity、MenuByResourceActivity、ContextMenuActivity
3.我們打開入口類:MainActivity,初始化Button如下:
package com.jeriffe.android.app; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.MenuInflater; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.PopupMenu; public class MainActivity extends Activity { public Button btnCreateByResource, btnCreateByCoding, btnPopupMenu, btnContextMenu; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SetupViews(); } private void SetupViews() { btnCreateByResource = (Button) findViewById(R.id.byresourceButton); btnCreateByResource.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent intent = new Intent(MainActivity.this, MenuByResourceActivity.class); startActivity(intent); } }); btnCreateByCoding = (Button) findViewById(R.id.bycodingButton); btnCreateByCoding.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent intent = new Intent(MainActivity.this, MenuByCodingActivity.class); startActivity(intent); } }); btnContextMenu = (Button) findViewById(R.id.contextMenuButton); btnContextMenu.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent intent = new Intent(MainActivity.this, ContextMenuActivity.class); startActivity(intent); } }); btnPopupMenu = (Button) findViewById(R.id.popupMenuButton); btnPopupMenu.setOnClickListener(new OnClickListener() { @SuppressLint("NewApi") public void onClick(View v) { PopupMenu popup = new PopupMenu(MainActivity.this, v); MenuInflater inflater = popup.getMenuInflater(); inflater.inflate(R.menu.activity_menu_by_resource, popup.getMenu()); popup.show(); } }); } }4.我們編輯MenuByCodingActivity如下:
package com.jeriffe.android.app; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.SubMenu; public class MenuByCodingActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_menu_by_coding); setTitle("硬編碼構建菜單"); } @Override public boolean onCreateOptionsMenu(Menu menu) { /* * add()方法的四個參數,依次是: 1、組別,如果不分組的話就寫Menu.NONE, * 2、Id,這個很重要,Android根據這個Id來確定不同的菜單 3、順序,那個菜單現在在前面由這個參數的大小決定 * 4、文本,菜單的顯示文本 */ SubMenu file = menu.addSubMenu(0, Menu.FIRST, 0, "File"); SubMenu edit = menu.addSubMenu(0, Menu.FIRST + 10, 0, "Edit"); SubMenu help = menu.addSubMenu(0, Menu.FIRST + 20, 0, "Help"); file.add(1, Menu.FIRST + 11, 0, "New"); file.add(1, Menu.FIRST + 12, 1, "Open"); file.add(1, Menu.FIRST + 13, 2, "Save"); file.add(1, Menu.FIRST + 14, 3, "Exit"); edit.add(2, Menu.FIRST + 11, 0, "Cut"); edit.add(2, Menu.FIRST + 12, 1, "Copy"); edit.add(2, Menu.FIRST + 13, 2, "Paste"); help.add(3, Menu.FIRST + 21, 0, "About"); help.add(3, Menu.FIRST + 22, 1, "Check Update"); return true; } }5.運行程序,主界面如下圖左一:
6.我們點擊第二個Button(通過硬編碼構建選項菜單)會看到如上圖左邊第二個,我們點擊紅色圈圈中的Action overflow會看到左3
點擊File會看到左4,點擊Edit會看到左5。
7.如果我們要實現單擊某一個菜單項來觸發事件如何操作?
這里也是so easy,我們只需重載onOptionsItemSelected(MenuItem item)方法即可。我們還可以實現菜單項,或者菜單組的單選設置,這里我們可以通過以下2格方法:
setCheckable(boolean checkable)
onOptionsItemSelected(MenuItem item)
代碼如下:
public class MenuByCodingActivity extends Activity { @Override public boolean onCreateOptionsMenu(Menu menu) { /* * add()方法的四個參數,依次是: 1、組別,如果不分組的話就寫Menu.NONE, * 2、Id,這個很重要,Android根據這個Id來確定不同的菜單 3、順序,那個菜單現在在前面由這個參數的大小決定 * 4、文本,菜單的顯示文本 */ SubMenu file = menu.addSubMenu(0, Menu.FIRST, 0, "File"); SubMenu edit = menu.addSubMenu(0, Menu.FIRST + 10, 0, "Edit"); SubMenu help = menu.addSubMenu(0, Menu.FIRST + 20, 0, "Help"); file.add(1, Menu.FIRST + 11, 0, "New"); file.add(1, Menu.FIRST + 12, 1, "Open"); file.add(1, Menu.FIRST + 13, 2, "Save"); file.add(1, Menu.FIRST + 14, 3, "Exit"); MenuItem item = edit.add(2, Menu.FIRST + 11, 0, "Cut"); /* * setCheckable (boolean checkable) :設置菜單項是否可以被勾選 */ item.setCheckable(true); edit.add(2, Menu.FIRST + 12, 1, "Copy"); edit.add(2, Menu.FIRST + 13, 2, "Paste"); /* * setGroupCheckable(int group, boolean checkable, boolean exclusive) * 設置group下的所有菜單項是否可以被勾選 如果第三個參數exclusive=true,則這格group下的菜單項將作為一組單選菜單項 */ edit.setGroupCheckable(2, true, false); help.add(3, Menu.FIRST + 21, 0, "About"); help.add(3, Menu.FIRST + 22, 1, "Check Update"); help.setGroupCheckable(3, true, true); return true; } @Override /* * 我們可以 重載onOptionsItemSelected方法來實現MenuItem單擊事件處理,也可以通過實現監聽器來操作 */ public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case Menu.FIRST: Toast.makeText(MenuByCodingActivity.this, "File 菜單被選擇", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 10: Toast.makeText(MenuByCodingActivity.this, "Edit 菜單被選擇", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 20: Toast.makeText(MenuByCodingActivity.this, "Help 菜單被選擇", Toast.LENGTH_LONG).show(); break; case Menu.FIRST + 11: Toast.makeText(MenuByCodingActivity.this, "New 菜單被選擇", Toast.LENGTH_LONG).show(); break; } return super.onOptionsItemSelected(item); } }運行程序如下所示:
至此我們第一個MenuAppDemo--硬編碼MenusDemo到此,結束。
通過資源文件來構建Menus
1.我們修改activity_menu_by_resource.xml(是MenuByResourceActivity對應的Menu資源文件)文件添加如上硬編碼實現的菜單結構
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/fileItem1" android:title="File"> <menu> <group android:id="@+id/group1" > <item android:id="@+id/fileitem2" android:title="New"/> <item android:id="@+id/fileitem3" android:title="Open"/> <item android:id="@+id/fileitem4" android:title="Save"/> <item android:id="@+id/fileitem5" android:title="Exit"/> </group> </menu> </item> <item android:id="@+id/editItem1" android:title="Edit"> <menu> <group android:id="@+id/group2" > <item android:id="@+id/edititem2" android:title="Cut"/> <item android:id="@+id/edititem3" android:title="Copy"/> <item android:id="@+id/edititem4" android:title="Paste"/> </group> </menu> </item> <item android:id="@+id/helpItem1" android:title="Help"> <menu> <group android:id="@+id/group3" > <item android:id="@+id/helpitem2" android:title="About"/> <item android:id="@+id/helpitem3" android:title="Check Update"/> </group> </menu> </item> <item android:id="@+id/Item1" android:title="Menu1"/> <item android:id="@+id/Item2" android:title="Menu2"/> <item android:id="@+id/Item3" android:title="Menu3"/> <item android:id="@+id/Item4" android:title="Menu4"/> </menu>2.我們修改MenuByResourceActivity如下:
package com.jeriffe.android.app; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MenuByResourceActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_menu_by_resource); setTitle("資源文件構建菜單"); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_menu_by_resource, menu); return true; } }運行程序,在主界面我們點擊第一個Button,如下圖左一紅色圈圈中的Button,之后的操作和上邊的示例:通過硬編碼來實現一樣。
上下文菜單(Context Menu)
上下文菜單的實現也是很容易的:
構建菜單:重載Activity的onCreateContextMenu方法
注冊菜單到指定的View:registerForContextMenu(View view)
重載Activity的onContextItemSelected(MenuItem item),如果我們要實現菜單項的單擊事件處理
我們還是通過實例來看如何實現:
我們接着上邊的Demo,我們這次只需修改ContextMenuActivity的代碼即可
這里我們構建菜單還是上邊的Menu資源文件
這里我們是把上下文菜單register到EditText
package com.jeriffe.android.app; import android.app.Activity; import android.os.Bundle; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.MenuItem; import android.view.View; import android.widget.EditText; public class ContextMenuActivity extends Activity { private EditText et; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_context_menu); et = (EditText) findViewById(R.id.editText1); registerForContextMenu(et); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { getMenuInflater().inflate(R.menu.activity_menu_by_resource, menu); } @Override public boolean onContextItemSelected(MenuItem item) { // 這里實現上下文菜單的菜單項單擊事件處理 return super.onContextItemSelected(item); } }運行程序,我們點擊主界面的第三個Button,如上圖左二,之后在EditView里長按鼠標左鍵,即可看到上下文菜單(如上圖右二)。
至此我們的上下文菜單就已經構建完成。
彈出菜單(Popup Menu)
彈出菜單的實例代碼在MainActivity里面,運行程序如上圖的右一
btnPopupMenu = (Button) findViewById(R.id.popupMenuButton); btnPopupMenu.setOnClickListener(new OnClickListener() { @SuppressLint("NewApi") public void onClick(View v) { PopupMenu popup = new PopupMenu(MainActivity.this, v); MenuInflater inflater = popup.getMenuInflater(); inflater.inflate(R.menu.activity_menu_by_resource, popup.getMenu()); popup.show(); } });
至此我們的3中菜單的演示就已經完成了。
***********************************************************
上邊實例都是在Android4.1.2中運行演示;下面是我在不同的Android版本中,選項菜單的不同效果:
Android2.2 WVGA800,這里看到的菜單效果和我的手機(S5830)的效果是一致的。
如果版本是SDK3.0或者SDK3.2(都是平板),那么效果也和SDK4.1.2大致一樣。
如果我刪除資源文件中的values-v11及values-v14文件(如下所示左一圈中的2個文件夾)SDK版本是4.1.2
如果AVD的Built-In為:WXGA720;那么運行效果如下中間的所示,由於沒有Menu硬件按鍵,我們無法操作。
如果是AVD的Built-In為:WVGA800;那么運行效果如下右一所示,由於我們有Menu硬件按鍵,我們可以操作菜單,但是效果確實3.0以前的效果。
如果我們保留values-v11及values-v14中的任何一個,那么運行效果和前面講解的演示效果是一樣的。
至於為什么不同版本的效果不同這個是Goolge更新導致:在Version11(SDK3.0)及以后的版本,Google正式宣布取消Android系統中MENU鍵的使用,也就是基於Android 3.0及以上系統的手機都應沒有MENU這一固定按鍵。所以菜單會出現在界面的右上角,也就是Action Bar的Action overflow中。
我們刪除的文件夾是對應V11和V14的,至於為什么刪除掉這2個文件夾,效果會和Version11以下的效果一致,我也不是太別清除,還望高手指點