安卓中的上下文操作模式ActionMode:email列表多选中用到的

使用上下文操作模式

上下文操作模式是ActionMode类的一个系统实现,它关注用户跟执行上下文操作的交互。当用户通过选择一个项目使这种模式成为可能的时候,一 个上下文操作栏就会显示在屏幕的顶部,并展现出用户在当前被选择的项目上能够执行的操作。当这种模式成为可能时,用户能够选择多个项目(如果应用程序允 许),或取消选择项目,并且可继续在Activity内浏览。当用户取消了所有选择的项目、按下BACK按钮、或选择操作栏左边的“执行”操作时,这种操 作模式就会被禁止,并且上下文操作栏也会被隐藏。

使用ActionMode,它会临时占据action bar的位置,但与ActionBar是独立的。

注意:上下文操作栏不必跟操作栏关联。它们独立的操作,上下文操作栏甚至可以显示在操作栏位置之上。

如果你依赖Android3.0(API级别 11)或更高的版本,你通常应该使用上下文操作模式来表现上下文操作,而不是浮动内容菜单。

对于那些提供上下文操作的View对象,你通常应该在以下两种事件之上调用上下文操作模式:

1.  用户在View对象上执行一个长按(long-click)操作。

2.  用户选择了一个复选框或View对象中类似复选框的UI组件。

你的应用程序如何调用上下文操作模式,并给每个操作定义行为,依赖于你的设计。有以下两种基本的设计:

1.  针对个别的、任意的View对象的上下文操作。

2.  针对ListView或GridView对象中项目组的批处理上下文操作(允许用户选择多个项目,并这些选择的项目上执行一个操作)。

针对个别View对象的上下文操作模式

如果你只想在用户选择特定的View对象时,调用上下文操作模式,应该按以下方法来做:

1.  实现ActionMode.Callback接口。在它的回调方法中,你能够针对上下文操作栏指定动作,在操作项目上响应点击事件和处理针对这个操作模式的其他生命周期事件。

2.  在显示这个操作栏时,调用startActionMode()方法(如用户长按(long-click)对应的view对象时)。

如:

1.   实现ActionMode.Callback接口:

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_menu, 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.menu_share:
                shareCurrentItem();
                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;
    }
};

我们注意到,这些回调方法处理把ActionMode对象传递给关联的事件之外,几乎完全跟选项菜单的回调方法相同。你能够使用 ActionMode的API对CAB(Context Action Bar)进行各种改变,如用setTitle()和setSubtitle()方法修改标题和子标题(有益于指示有多少项目被选择了)。

我还看到,上例中,当操作模式被销毁时,把mActionMode变量设置为null,接下来,你能看到它是如何被初始化的,以及如何把成员变量保存在你的Activity或Fragment中。

2.  在适当的时机调用startActionMode()方法启用上下文操作模式,如在响应一个View对象的长按事件时:

someView.setOnLongClickListener(new View.OnLongClickListener() {
    // Called when the user long-clicks on someView
    public boolean onLongClick(View view) {
        if (mActionMode != null) {
            return false;
        }
  
        // Start the CAB using the ActionMode.Callback defined above
        mActionMode = getActivity().startActionMode(mActionModeCallback);
        view.setSelected(true);
        return true;
    }
});

当你调用startActionMode()方法时,系统返回被创建的ActionMode对象。通过把这个对象保存在一个成员变量中,你能够在对 其他事件的响应中对上下文菜单进行改变。在上例中,在启动这种操作模式之前,通过检查ActionMode对象的实例是否为null,来确保这个对象实例 不被重复创建。

在ListView或GridView对象中的批处理上下文操作

如果在ListView或GridView对象(或是另外的AbsListView类的扩展)中有一个项目的集合,并且你想要允许用户对其执行批处理操作,那么你应该按如下的方法做:

1.  实现AbsListView.MultiChoiceModeListener接口,并且要用 setMultiChoiceModeListener()方法把它设置给ViewGroup对象。在这个监听器的回调方法中,你能够给这个上下文操作栏 指定动作,响应在操作项目上的点击事件,并且处理从ActionMode.Callback接口中继承来的其他回调方法。

2.  调用带有CHOICE_MODE_MULTIPLE_MODAL参数的setChoiceMode()方法。

例如:

ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.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.menu_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, 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;
    }
});

现在,当用户用长按事件选择一个项目时,系统会调用onCreateActionMode()方法,并显示带有特定操作的上下文操作栏。同时在上下文操作栏显示时,用户还能继续选择其他的项目。

在某些场景中,上下文操作会给一些项目提供共通的操作,因此你可能想要添加复选框或类似的允许用户选择项目的UI元素,因为它们可能没有长按事件行 为,所以在用户选择复选框时,你能够通过设置各自列表项的复选状态的setItemChecked()方法来调用上下文操作模式。