Android Contextual Menus之二:contextual action mode
Android Contextual Menus之二:contextual action mode
接上文:Android Contextual Menus之一:floating context menu
ContextMenu的两种形式,上文讨论了第一种形式,兼容性较好。
本文讨论第二种形式,Android 3.0,即API Level 11之后可用。
Contextual action mode
Contextual action mode是 ActionMode
的系统实现,关注于执行上下文相关动作的用户交互。
当用户通过选择一个项目使能这个模式,一个contextual action bar就会出现在屏幕上方,显示用户对当前选中的项目可以执行的动作。
当这个模式使能时,用户可以:选择多个项目(如果你允许的话)、取消项目选择、在activity中继续浏览(只要你允许)。
当用户取消对所有项目的选择、按下Back键、或者点击bar左边的完成按钮之后,action mode就被禁用,contextual action bar消失。
注意:contextual action bar没有必须和 action bar关联,它们是独立的。
CAB的使用情形
对于提供上下文动作的View,通常在这两种情况下(情况之一或both)调用contextual action mode:
1.用户在View上长按;
2.用户选择了View中的CheckBox或者类似控件。
你的应用如何invoke这个contextual action mode,以及如何定义每个action取决于你自己的设计。
两种基本的设计:
1.对个体任意views的上下文相关操作;
For contextual actions on individual, arbitrary views.
2.对一组数据的批处理,比如ListView或GridView中的项目,允许用户选择多个项目然后对它们整体执行一个动作。
For batch contextual actions on groups of items in a ListView or GridView (allowing the user to select multiple items and perform an action on them all).
下面分别讲讲这两种情景下的实现。
Enabling the contextual action mode for individual views
如果你想在用户选择指定View的时候invoke contextual action mode(CAB),你应该:
1.实现ActionMode.Callback
接口。
在这个接口的回调方法中,你可以指定contextual action bar的动作,响应action items的点击事件,还有处理action mode的生命周期事件。
2.当你想要show这个bar的时候(比如用户长按view的时候),调用 startActionMode()
方法。
例子代码:
package com.example.mengdd.hellocontextmenu; import android.app.Activity; import android.os.Bundle; import android.view.ActionMode; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnLongClickListener; import android.widget.TextView; import android.widget.Toast; public class ContextualActionModeActivity extends Activity { private TextView mTextView = null; private ActionMode mActionMode = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_contextual_action_mode); mTextView = (TextView) findViewById(R.id.textView2); mTextView.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View view) { if (mActionMode != null) { return false; } // Start the CAB using the ActionMode.Callback defined above mActionMode = startActionMode(mActionModeCallback); view.setSelected(true); return true; } }); } private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { // Called when the action mode is created; startActionMode() was called @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Inflate a menu resource providing context menu items MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.context_menu1, menu); return true; } // Called each time the action mode is shown. Always called after // onCreateActionMode, but // may be called multiple times if the mode is invalidated. @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; // Return false if nothing is done } // Called when the user selects a contextual menu item @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.edit: showEditor(); mode.finish(); // Action picked, so close the CAB return true; default: return false; } } // Called when the user exits the action mode @Override public void onDestroyActionMode(ActionMode mode) { mActionMode = null; } }; private void showEditor() { Toast.makeText(ContextualActionModeActivity.this, "edit", Toast.LENGTH_LONG).show(); } }
Enabling batch contextual actions in a ListView or GridView
对于ListView和GridView这样的集合类,想让用户进行批处理操作,应该如下:
1.实现 AbsListView.MultiChoiceModeListener
接口,通过setMultiChoiceModeListener()方法把它set进集合类控件。
在这个listener的回调方法中,你可以指定contextual action bar的动作,响应action item的点击事件,处理其他继承自ActionMode.Callback的回调。
2.调用 setChoiceMode()
方法,使用参数 CHOICE_MODE_MULTIPLE_MODAL
。
例子代码:
package com.example.mengdd.hellocontextmenu; import android.app.ListActivity; import android.os.Bundle; import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; import android.view.MenuInflater; import android.widget.AbsListView.MultiChoiceModeListener; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; public class ListCABActivity extends ListActivity { private ListView mListView = null; private String[] mStrings = Cheeses.sCheeseStrings; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Use an existing ListAdapter that will map an array // of strings to TextViews setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mStrings)); mListView = getListView(); mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); mListView.setMultiChoiceModeListener(new MultiChoiceModeListener() { @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { // Here you can do something when items are // selected/de-selected, // such as update the title in the CAB } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { // Respond to clicks on the actions in the CAB switch (item.getItemId()) { case R.id.delete: deleteSelectedItems(); mode.finish(); // Action picked, so close the CAB return true; default: return false; } } @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Inflate the menu for the CAB MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.context_menu2, menu); return true; } @Override public void onDestroyActionMode(ActionMode mode) { // Here you can make any necessary updates to the activity when // the CAB is removed. By default, selected items are // deselected/unchecked. } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // Here you can perform updates to the CAB due to // an invalidate() request return false; } }); } private void deleteSelectedItems() { Toast.makeText(ListCABActivity.this, "delete!", Toast.LENGTH_LONG) .show(); } }
参考资料
API Guides: Menus->Using the contextual action mode
http://developer.android.com/guide/topics/ui/menus.html#CAB