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();    }}
CAB Demo1

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();    }}
CAB Demo2

参考资料

  API Guides: Menus->Using the contextual action mode

  http://developer.android.com/guide/topics/ui/menus.html#CAB

更多相关文章

  1. Android(安卓)Wear Preview - UI
  2. Android(安卓)android下的电话拨号器
  3. [Android(安卓)UI界面] Android(安卓)UI 设计准则
  4. 介绍本人的一个Android项目(附源代码)
  5. Android(安卓)调试:java 跨工程调试 android 项目
  6. Android将允许纯C/C++开发应用(上)
  7. Android(安卓)适配---notification led 呼吸灯
  8. 记录一下八款开源 Android(安卓)游戏引擎
  9. Android应用程序的类型

随机推荐

  1. 用jquery技术实现table的奇数行变色
  2. JQuery自动完成功能不会显示所有结果
  3. 在发出xml Ajax请求时获取错误412
  4. jQuery向父级元素最前面添加元素—prepen
  5. 动态更改设置值?
  6. jquery lazyload延迟加载技术的实现原理
  7. 复选框上的反应仅适用一次。哪里不对?
  8. jQuery UI对话框调整大小关闭按钮
  9. 如何在jQuery中选择最后一个子元素?
  10. 在引导程序弹出窗口中使用交互式元素