安卓开发——浮动上下文选项与上下文菜单栏的实现

上下文菜单就是在界面中,尤其是列表项等视图中长按一个条目时,会弹出一个浮动的上下文菜单选项,或者是进入列表的多选界面。

浮动的上下文选项

首先我们要在res/menu目录中添加菜单项布局文件(list\_item\_context.xml)。

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_fragment_crime_list_delete"
android:icon="@android:drawable/ic_menu_delete"
android:title="@string/list_item_delete">
</item>
</menu>

  然后我们要实现浮动上下文选项菜单和响应相应菜单选项的处理则要重载以下两个函数:

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

  2. public boolean onContextItemSelected(MenuItem item);

具体实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
getActivity().getMenuInflater().inflate(R.menu.list_item_context, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.list_item_delete:
/* 在这里处理相应按钮的事件 */
return true;
...
default: ...
}
return super.onContextItemSelected(item);
}

注意:默认情况下,长按视图不会触发上下文菜单的创建。要触发菜单的创建,必须调用以下
Fragment方法为浮动上下文菜单登记一个视图:registerForContextMenu(listView)。 在实际开发中推荐在Fragment的onCreateView()方法中进行注册。

1
2
3
4
5
6
7
8
9
10
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = super.onCreateView(inflater, container, savedInstanceState);
/* 为Listview中的选项创建浮动上下文菜单 */
ListView listView = (ListView) v.findViewById(android.R.id.list);
registerForContextMenu(listView);
...
return v;
}

上下文操作模式

(1)首先我们在Fragment.onCreateView(...)方法中,设置列表视图的选择模式为CHOICE_MODE_MULTIPLE_MODAL。(适当时候要考虑版本兼容性问题)

(2)然后我们要给ListView设置一个实现AbsListView.MultiChoiceModeListener接口的监听器。

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 View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = super.onCreateView(inflater, container, savedInstanceState);
ListView listView = (ListView) v.findViewById(android.R.id.list);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode actionMode, int i, long l, boolean b) {
//暂时没有实现
}
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
/* 实例化操作栏上的菜单项,这里的布局xml可用浮动上下文菜单的菜单项 */
actionMode.getMenuInflater().inflate(R.menu.fragment_list_context_item, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
//暂时没有实现
}
@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.fragment_list_context_button:
...处理按钮事件
return true;
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode actionMode) {
//暂时没有实现
}
});
...
return v;
}

(3)修改已被选中条目的显示背景。创建一个res/drawable目录,然后以selector为根元素在该目录下新建一个名为background_activated.xml的文件。

1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true"
android:drawable="@android:color/darker_gray"></item>
</selector>

然后修改列表项条目布局文件的属性 (这里只是例子说明,主要是观察 android:background 属性的应用):

1
2
3
4
5
6
7
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/background_activited">
....
</RelativeLayout>