调用onDestroyActionMode后重新打开ActionMode(或CAB)

时间:2013-08-31 10:16:30

标签: android contextual-action-bar android-actionmode

让我们看看这种情况:你已经打开了DAB&屏幕上的DISCARD选项包含要填写的表单,您不会接受字段的错误值。因此,用户应该填写有效值(并按Back / Done以接受它)或按CAB上的Discard。

按DONE立即启动onDestroyActionMode(),然后关闭CAB。 因此,这是启动有效性检查的地方(onBackPressed()旁边)。

问题是,如果在那里创建一个新的ActionMode(如果表单有效性检查失败),将启动递归循环(因为新的CAB将首先开始关闭旧的,依此类推) - >的StackOverflowError。

我尝试创建一个状态变量来防止StackOverflowError,但在这种情况下它只能每隔一次(并且只有onBackPressed())起作用: - /

那么,问题:如何在调用onDestroyActionMode()后立即打开CAB(或如何重新打开新的?)?

3 个答案:

答案 0 :(得分:4)

第一位评论者确实是正确的。动作模式是瞬态的,可以由用户随时通过设计完成。它们用于表示类似批处理选择的内容,您可以在对整个集合进行操作之前添加或删除,邮件分类和文本编辑就是两个示例。完成动作模式应该是非破坏性的,就像取消对话一样。它不应被视为确认步骤。

说到文本编辑,你强烈暗示这里涉及的表单包含文本字段。当用户突出显示某些文本并且TextView启动其自己的编辑操作模式时会发生什么?启动动作模式将隐式完成任何当前动作模式。

您应该使用其他示意图来表达正在进行的编辑。

答案 1 :(得分:0)

回答核心问题:如何在重新按下后重新创建一个ActionMode:

您可以将Runnable postDelayed到Handler以重新创建ActionMode。设备之间所需的延迟可能会有所不同,我发现200ms可以处理我尝试过的所有内容。在Activity或FragmentActivity中尝试以下片段:

RepeatActionModeRunnable mRepeatActionModeRunnable;
Handler mHandler = new Handler();

@Override
protected void onPause() {
    mHandler.removeCallbacks(mRepeatActionModeRunnable);
    super.onPause();
}

private class RepeatActionModeRunnable implements Runnable {
    ActionMode.Callback mRepeatActionMode;
    public RepeatActionModeRunnable(ActionMode.Callback actionMode) {
        mRepeatActionMode = actionMode;
    }
    @Override
    public void run() {
        mActionMode = startActionMode(mRepeatActionMode);
    }
}

然后在onDestroyActionMode中,您可以在需要时使用它(例如,您无疑需要一些逻辑包装来检测它是否应该重新创建):

mHandler.removeCallbacks(mRepeatActionModeRunnable);
mRepeatActionModeRunnable = new RepeatActionModeRunnable(new SomeActionMode());
mHandler.postDelayed(mRepeatActionModeRunnable, 200);

至于是否将CAB用于表格/数据输入,这种情况非常适合“行动呼吁”,这也是ActionMode模式的原因。障碍/细微差别/错误的存在,例如在后退按钮后重新创建以及如果用户选择要编辑的文本,不应该构成它不能使用的理由,而不是它被视为可能不是阻力最小的路径在解决方案方面(这是一个挑战!)。 '完成&存在'的存在单独丢弃'模式也不应构成在涉及数据输入的情况下不使用ActionMode的基本原理。这些都是可能适合您的情况的可能性,而不是正确或错误的方式。

PS:关于如何处理TextSelectionCAB,这是一个解决方案:Detect ActionMode nesting

答案 2 :(得分:0)

实际上,你可以做这样的事情,然后就不再有StackOverflowException了。:

 @Override
        public void onDestroyActionMode(ActionMode mode) {
            //your code
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    startSupportActionMode(mActionCallBack);
                }
            });
        }