让我们看看这种情况:你已经打开了DAB&屏幕上的DISCARD选项包含要填写的表单,您不会接受字段的错误值。因此,用户应该填写有效值(并按Back / Done以接受它)或按CAB上的Discard。
按DONE立即启动onDestroyActionMode()
,然后关闭CAB。
因此,这是启动有效性检查的地方(onBackPressed()
旁边)。
问题是,如果在那里创建一个新的ActionMode(如果表单有效性检查失败),将启动递归循环(因为新的CAB将首先开始关闭旧的,依此类推) - >的StackOverflowError。
我尝试创建一个状态变量来防止StackOverflowError,但在这种情况下它只能每隔一次(并且只有onBackPressed()
)起作用: - /
那么,问题:如何在调用onDestroyActionMode()
后立即打开CAB(或如何重新打开新的?)?
答案 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);
}
});
}