應用系統中最常見的組織功能的方式之一就是菜單。 Android系統中有兩種菜單:OptionMenu和ContextMenu. OptionMenu就是點擊Menu按鈕時顯示的菜單(在3.0以后的版本,可能沒有Menu按鈕,而是由一個Action Bar). ContextMenu是指用戶長時間按住屏幕時顯示的Menu(在3.0以后的版本中,Android推薦使用ActionMode).
以我們的餐館系統為例,在餐館列表界面,我們需要兩種菜單。當用戶點擊菜單按鈕時,需要顯示[新建]這個菜單,在用戶長時間按住某個餐館時,我們要顯示一個Context菜單。這個Context菜單包括[新建],[編輯],[刪除]三項。如果餐館是金牌餐館,那么不能直接刪除,所以此時刪除菜單要禁用。
Android系統中,如果需要使用Menu按鈕,
- 首先需要重寫onCreateOptionsMenu來響應用戶點擊菜單按鈕的事件
- 重寫onOptionsItemSelected來響應菜單項點擊事件。
但是我們的這個例子中還用到了onPrepareOptionsMenu。這個方法在每次菜單顯示之前執行。我們使用這個事件的原因是我們的Options Menu和Contextual Menu使用的是同一個菜單資源文件,我們需要在這里通過代碼隱藏更新和刪除菜單項(因為我們沒有提供選擇功能)。
使用Context菜單的流程有點不同。對於我們的ListView而言,
- 首先調用Activity的registerForContextMenu方法通知Activity,我們的ListView需要使用ContextMenu.
- 然后重寫onCreateContextMenu,當用戶長按住ListView的時候,這個方法會被調用來創建菜單。
- 最后重寫onContextItemSelected處理事件響應, 當用戶點擊了菜單項的時候,Android調用這個方法。
最后要提到的一件事,其實是應該最先做的,那就是定義菜單資源文件。
菜單資源文件
我在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"
?>
<
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
按照前面的介紹,我們需要重寫下面的三個方法,方法的內容都很簡單,就不需要再介紹了.
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這個參數也要用上才可以。
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);
}
|
顯示效果
運行效果截圖: