Android 開發 – 使用菜單


應用系統中最常見的組織功能的方式之一就是菜單。 Android系統中有兩種菜單:OptionMenu和ContextMenu. OptionMenu就是點擊Menu按鈕時顯示的菜單(在3.0以后的版本,可能沒有Menu按鈕,而是由一個Action Bar). ContextMenu是指用戶長時間按住屏幕時顯示的Menu(在3.0以后的版本中,Android推薦使用ActionMode).

以我們的餐館系統為例,在餐館列表界面,我們需要兩種菜單。當用戶點擊菜單按鈕時,需要顯示[新建]這個菜單,在用戶長時間按住某個餐館時,我們要顯示一個Context菜單。這個Context菜單包括[新建],[編輯],[刪除]三項。如果餐館是金牌餐館,那么不能直接刪除,所以此時刪除菜單要禁用。

Android系統中,如果需要使用Menu按鈕,

  1. 首先需要重寫onCreateOptionsMenu來響應用戶點擊菜單按鈕的事件
  2. 重寫onOptionsItemSelected來響應菜單項點擊事件。

但是我們的這個例子中還用到了onPrepareOptionsMenu。這個方法在每次菜單顯示之前執行。我們使用這個事件的原因是我們的Options Menu和Contextual Menu使用的是同一個菜單資源文件,我們需要在這里通過代碼隱藏更新和刪除菜單項(因為我們沒有提供選擇功能)。

使用Context菜單的流程有點不同。對於我們的ListView而言,

  1. 首先調用Activity的registerForContextMenu方法通知Activity,我們的ListView需要使用ContextMenu.
  2. 然后重寫onCreateContextMenu,當用戶長按住ListView的時候,這個方法會被調用來創建菜單。
  3. 最后重寫onContextItemSelected處理事件響應, 當用戶點擊了菜單項的時候,Android調用這個方法。

最后要提到的一件事,其實是應該最先做的,那就是定義菜單資源文件。

菜單資源文件

我在res文件夾下新建了一個menu文件夾。然后新建了一個restaurant_list_view.xml。下面是文件內容:

?
res/menu/restaurant_list_view.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<? xml version = "1.0" encoding = "utf-8" ?>
< menu xmlns:android = "http://schemas.android.com/apk/res/android" >
  
     < item
         android:id = "@+id/r000_create_restaurant"
         android:title = "新建" >
     </ item >
     < item
         android:id = "@+id/r000_update_restaurant"
         android:title = "編輯" >
     </ item >
     < item
         android:id = "@+id/r000_delete_restaurant"
         android:title = "刪除" >
     </ item >
  
</ menu >

使用Option Menu

按照前面的介紹,我們需要重寫下面的三個方法,方法的內容都很簡單,就不需要再介紹了.

?
onCreateOptionsMenu&onPrepareOptionsMenu&onOptionsItemSelected
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override
public boolean onCreateOptionsMenu(Menu menu) {
     new MenuInflater( this ).inflate(R.menu.restaurant_list_form, menu);
     return super .onCreateOptionsMenu(menu);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu){
     menu.findItem(R.id.r000_delete_restaurant).setVisible( false );
     menu.findItem(R.id.r000_update_restaurant).setVisible( false );
     return super .onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
     if (item.getItemId() == R.id.r000_create_restaurant) {
         Intent intent = new Intent( this , RestaurantDetailsEditor. class );
         this .startActivityForResult(intent, RequestCode_CreateRestaurant);
     }
     return super .onOptionsItemSelected(item);
}

使用Context Menu

按照前面的介紹,我們需要寫的代碼分為三部分.下面是具體的代碼。這段代碼通過getSelectedRestaurant方法演示了如何使用onCreateContextMenu的menuInfo這個參數。如果同一個界面上有多個View需要Context Menu,那么view這個參數也要用上才可以。

?
registerForContextMenu&onCreateContextMenu&onContextItemSelected
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public void onCreate(Bundle savedInstanceState) {
     super .onCreate(savedInstanceState);
     setContentView(R.layout.main);
  
     this .restaurantDataProvider = new MemoryRestaurantDataProvider();
     this .restaurantListView = (ListView) findViewById(R.id.restaurant_list_view);
     this .restaurantListAdapter = new RestaurantListAdapter( this ,
             this .restaurantDataProvider.getRestaurants());
     this .restaurantListView.setAdapter( this .restaurantListAdapter);
     this .restaurantListView.setOnItemSelectedListener(onRestaurantSelected);
     this .restaurantListView.setOnItemClickListener(onItemClicked);
     this .registerForContextMenu( this .restaurantListView);
}
     @Override
public void onCreateContextMenu(ContextMenu menu, View view,
         ContextMenuInfo menuInfo) {
     super .onCreateContextMenu(menu, view, menuInfo);
     Restaurant dataItem = getSelectedRestaurant(menuInfo);
     if (dataItem != null ) {
         this .getMenuInflater().inflate(R.menu.restaurant_list_form, menu);
         menu.findItem(R.id.r000_delete_restaurant).setEnabled(
                 !dataItem.isGoldenBrand());
     }
}
  
private Restaurant getSelectedRestaurant(ContextMenuInfo menuInfo) {
     Restaurant dataItem = null ;
     AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
     dataItem = this .restaurantListAdapter.getItem(adapterMenuInfo.position);
     return dataItem;
}
  
@Override
public boolean onContextItemSelected(MenuItem item) {
  
     switch (item.getItemId()) {
     case R.id.r000_update_restaurant:
         break ;
     case R.id.r000_delete_restaurant:
         break ;
     }
     return super .onContextItemSelected(item);
}

顯示效果

運行效果截圖:

image

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM