1

让我们看看这种情况:您在屏幕上打开了一个带有 DONE & DISCARD 选项的 CAB,并且您将不接受字段的错误值。因此,用户应该填写一个有效值(并按 Back/Done 以使其被接受)或按 CAB 上的 Discard。

按下 DONEonDestroyActionMode()立即启动,之后 CAB 关闭。onBackPressed()因此,这是启动有效性检查的位置(在 旁边)。

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

我尝试创建一个状态变量来防止 StackOverflowError,但在这种情况下,它仅每两次(并且仅onBackPressed())一次有效:-/

所以,问题是:我如何在调用 CAB 后立即保持打开(或如何重新打开一个新的)onDestroyActionMode()

4

3 回答 3

4

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

说到文本编辑,您在很大程度上暗示此处涉及的表单包含文本字段。当用户突出显示某些文本并且 TextView 启动其自己的编辑操作模式时会发生什么?启动一个动作模式将隐式结束任何当前的动作模式。

您应该使用另一种可供性来表达正在进行的编辑。

于 2013-09-02T23:24:24.810 回答
0

实际上,您可以这样做,那么就不会再出现 StackOverflowException 了:

 @Override
        public void onDestroyActionMode(ActionMode mode) {
            //your code
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    startSupportActionMode(mActionCallBack);
                }
            });
        }
于 2014-04-12T03:19:40.243 回答
0

回答核心问题:如何在背压后重新创建 ActionMode:

您可以将延迟的 Runnable 发布到 Handler 以重新创建 ActionMode。所需的延迟在设备之间可能会有所不同,我发现 200 毫秒可以处理我尝试过的所有内容。在 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

于 2013-10-01T16:07:01.627 回答