Menu的功能:給用戶提供一個可以進行管理,設置,以及不常用功能的整理和集合;
Menu如何設置:采用XML可以實現(java代碼也可以創建);
Menu由Activity來加載和顯示的,需要重寫Activity的方法;
Activity需要重寫方法進行菜單加載,以及菜單點擊的處理
菜單可以分為三類:
1,上下文菜單(ContextMenu):長按某一個View,出現的菜單,稱為上下文菜單(只出現在屏幕中間),類似於Windows的右鍵菜單
2,OptionsMenu:在Activity標題欄中,顯示的菜單
3,PopupMenu:Android3.0以后添加的心功能,用來改進上下文菜單的顯示效果(可顯示在任意位置);
OptionsMenu
OptionsMenu是由Activity來加載的,才可以顯示在標題欄上,Activity需要重寫onCreateOptionsMenu(Menu,Menu)方法,來設置Activity的菜單;
<?xml version="1.0" encoding="utf-8"?> <!--需要在layout中創建menu文件夾,然后創建菜單文件,通過xml描述的菜單--> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <!--名詞:菜單(menu),菜單項(menu item)--> <item android:id="@+id/action_sets" android:title="設置" /> <item android:id="@+id/action_help" android:title="help" /> </menu>
/** * !!!這個OptionMenu的創建,只會調用一次 * 當Activity啟動之后,需要進行菜單的加載, * 如果是實現了這個方法,並且menu菜單中,添加了菜單項menu item * Activity將會自動的支持菜單的顯示; * @param menu * @return true 菜單可以顯示,false 菜單不會顯示 */ @Override public boolean onCreateOptionsMenu(Menu menu) { //1,加載菜單,使用MenuInflater來加載,對應Activity已經包含一個menuInflater對象,可以直接使用 menuInflater = getMenuInflater(); //解析menu菜單文件,並且自動的將菜單添加到指定的參數2菜單中 menuInflater.inflate(R.menu.main_menu,menu); return true; } /** * 當OptionMenu被選中的時候,回調此方法 * @param item * @return true-->代表當前的菜單點擊處理,已經處理過了 */ @Override public boolean onOptionsItemSelected(MenuItem item) { //因為這個方法,所有菜單都公用,所以需要通過menu的id來進行區分 switch (item.getItemId()){ case R.id.action_sets: Toast.makeText(this,"action_sets",Toast.LENGTH_SHORT).show(); break; case R.id.action_help: Toast.makeText(this,"action_help",Toast.LENGTH_SHORT).show(); break; } return true; }
1,程序中onCreateOptionsMenu(Menu menu)方法,Activity自身含有的方法,只要重寫該方法,系統會自動完成點擊的時間調用;
2,onOptionsItemSelected(MenuItem item)方法為菜單的點擊事件
3,MenuItem需要設置Id,來進行點擊的判斷;
4,菜單項id的通用規則:以“action_”開頭,后面附帶功能表示的單詞;
ContextMenu
1,通常上下文菜單通過手指長按才會顯示;
2,彈出一個浮動在界面上方的類似於對話框性質的界面;
3,上下文菜單點擊,同樣會出發相應的操作;
4,上下文菜單通常都是和點擊的條目相關
上下文菜單的特點:針對特定的內容,進行的菜單顯示;不同的內容,顯示出來的菜單項也不同;
上下文菜單的加載方式:
與OptionMenu類似,都是同時能過回調來設置菜單的;
使用XML描述菜單,通過MenuInflater來加載菜單;
上下文菜單的觸發和現實的機制:通過控件的長按來完成的;ListView/GridView默認支持上下文菜單
onCreateContextMenu()方法,通過參數3ContextMenuInfo可以傳遞附加信息,例如ListView,可以確定當前選擇的Item的位置
上下文菜單的注冊:
registerForContextMenu(View)---->注冊上下文菜單
unregisterForContextMenu(View)--->釋放上下文菜單的注冊
步驟:
1,注冊View來顯示ContextMenu
2,實現Activity onCreateContextMenu()就可以顯示;
3,處理點擊:
點擊上下文的時候,通常只有在ListView或者GridView的時候,才能夠獲取MenuInfo,來判斷長按的是哪一項;
對於普通的View而言,菜單無法獲取選中的是哪個View,通常需要使用成員變量來實現內容的訪問;
onContextItemSelected(MenuItem item)是上下文菜單的點擊處理方法,ContextMenuInfo轉換AdapterContextMenuInfo獲取位置;
Android當中,關於時間的處理,凡是帶有Boolean返回類型事件,都有一個含義,如果返回true,事件不會再繼續執行public class ContactActivity extends Activity { private ArrayAdapter<String> arrayAdapter; private List<String> items; private ListView lv; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_contact); lv = (ListView) findViewById(R.id.lv); items = new LinkedList<String>(); for (int i = 0; i <50 ; i++) { items.add("item"+i); } arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,items); lv.setAdapter(arrayAdapter); registerForContextMenu(lv); } @Override protected void onDestroy() { unregisterForContextMenu(lv); super.onDestroy(); } /** * 每一個上下文菜單,需要顯示的時候,這個方法,就會被調用; * @param menu ContextMenu和Menu類似,里面可以添加多個菜單項; * @param v 實際上就是被長按的那個控件,v不同導致菜單不一樣; * @param menuInfo 菜單在創建的時候,附加的信息,只有在listView和GridView item長按的時候才有效 */ @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.context_image_menu,menu); } /** * 類似於onOptionsItemSelected,都是菜單項,點擊之后,回調此方法,進行菜單事件的處理 * @param item * @return true-->當前菜單項的處理已經完成了,false-->讓Activity自己來處理 */ @Override public boolean onContextItemSelected(MenuItem item) { //從ListView中,長按出發的上下文菜單,每一個Item都會包含一個叫做MenuIfo的數據,這個數據包含了長按menu的位置 switch(item.getItemId()){ case R.id.action_image_save: ContextMenu.ContextMenuInfo menuInfo = item.getMenuInfo(); if(menuInfo!=null){ AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; int position = info.position; items.remove(position); arrayAdapter.notifyDataSetChanged(); } break; case R.id.action_image_large: ContextMenu.ContextMenuInfo menuInfo1 = item.getMenuInfo(); if(menuInfo1!=null){ AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo1; int position = info.position; Toast.makeText(this,""+position,Toast.LENGTH_SHORT).show(); } break; } return true; } }
PopupMenu
Android3.0以后提出,可以直接顯示在制定空間上的菜單,不再需要長按,而是通過代碼來指定顯示的控件及其位置;
其特點:必須通過創建new PopupMenu(Context,View),第二個參數代表菜單以哪個控件為基准來顯示;PopupMenu雖然可以通過setOnMenuItemClickListener來設置菜單的點擊事件處理,但是,PopupMenu和ContextMenu一樣,都需要獲取當前點擊位置的信息;
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/action_image_save" android:title="刪除" /> <item android:id="@+id/action_image_large" android:title="修改" /> </menu>
public class PopupMenuActivity extends Activity implements PopupMenu.OnMenuItemClickListener { /** * 用於顯示的彈出菜單 */ private PopupMenu popupMenu; private MenuInflater menuInflater; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_popup_menu); } /** * 顯示PopupMenu * @param view */ public void btnShowPopup(View view) { if(popupMenu==null){ //創建PopupMenu,參數2:指定菜單與哪個控件挨着 popupMenu = new PopupMenu(this,view); //設置菜單項,從xml加載 //獲取菜單加載器 menuInflater = popupMenu.getMenuInflater(); menuInflater.inflate(R.menu.context_image_menu,popupMenu.getMenu()); popupMenu.setOnMenuItemClickListener(this); } //顯示菜單 popupMenu.show(); } /** * 菜單項 點擊的時候的調用 * @param item * @return */ @Override public boolean onMenuItemClick(MenuItem item) { switch(item.getItemId()){ case R.id.action_image_save: Toast.makeText(this,"保存圖片",Toast.LENGTH_SHORT).show(); break; } return true; } }