【问题标题】:Detect ActionMode nesting检测 ActionMode 嵌套
【发布时间】:2013-05-15 14:27:34
【问题描述】:

我在我的应用程序中使用了一些自定义的 ActionMode。当一个动作模式关闭时,我会做一些家务,比如关闭相关视图、更新更改等。我在 OnDestroyActionMode 中检测到动作模式已关闭。

我的问题是,当在我的一些 ActionModes 中时,用户可能会触发另一个系统 actionmode(文本复制/粘贴/选择)。在这种情况下,onDestroyActionMode 被调用,我错误地认为用户完成了第一个动作模式,而不是实现“堆栈”功能,所以我可以忽略这个 onDestroyActionMode,让用户编辑/剪切/等文本,然后重新打开完成后的前操作模式。

我怎样才能做到这一点?

【问题讨论】:

    标签: android nested ondestroy actionmode


    【解决方案1】:

    进一步阐明您的情况:在蜂窝之前,TextView 上的 longPress 将产生一个弹出窗口,其中包含选项(例如“选择单词”、“全选”和“将“某些单词”添加到字典中),但不会影响任何现有的 ActionMode,无论是在显示时还是在关闭时(通过按回)。所以这不是蜂窝前的问题。

    关于 HTC Sense 的更多信息:Sense 不支持 TextView.setCustomSelectionActionModeCallback(),因为 Sense 不使用 ActionMode 来进行文本选择功能(显然不关心世界其他地方是否这样做!)。所以这个问题在那种情况下会有不同的味道(我没有在 Sense 下测试过下面的解决方案,所以不确定它会如何表现)。

    一种解决方案是创建您自己的自定义 ActionMode.Callback 来替换操作系统的,并将其应用到您想要的任何 TextView 和/或 EditText 的 setCustomSelectionActionModeCallback() 中(尽管仅当设备运行蜂窝或更高版本时)。将自定义的onTextSelectionCABDestroyed回调接口传给你自定义的ActionMode.Callback,在onDestroyActionMode方法中调用。

    首先创建一个接口并在您想要处理原始 ActionMode 重新创建的地方实现它(或者您可能希望使用带有 Otto 之类的总线事件):

    public interface YourCallbackInterface {
        public void onTextSelectionCABDestroyed();
    }
    

    并创建一个新类:

    public final class CustomTextSelectionActionModeCallback implements ActionMode.Callback {
    WeakReference<YourCallbackinterface> mYourCallbackinterface;
    public CustomTextSelectionActionModeCallback(YourCallbackinterface yourCallbackInterface) {
        mYourCallbackinterface = new WeakReference<YourCallbackinterface>(yourCallbackInterface);
    }
    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        return false;
    }
    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        return true;    //returning true will create the ActionMode
    }
    @Override
    public void onDestroyActionMode(ActionMode mode) {
        //this is the magic where we actually capture the destroy event for TextSelectionCAB and can subsequently do things like recreate the ActionMore that TextSelectionCAB greedily destroyed!
        mYourCallbackinterface.get().onTextSelectionCABDestroyed();
    }
    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }
    

    }

    并且记住在从 ActionMode 的 onDestroyActionMode 重新创建 ActionMode 时避免 StackOverflowException,将 Runnable 延迟到 Handler 就像我在这里解释的那样:Reopen ActionMode (or CAB) after onDestroyActionMode is called

    最后,如果您使用 ActionBarSherlock,请确保您的 CustomTextSelectionActionModeCallback 实现 android.view.ActionMode.Callback 而不是 com.actionbarsherlock.view.ActionMode.Callback。

    注意:我没有玩过 ActionBarCompat,所以不确定这一切如何适用。如果有人知道,请发表评论!

    【讨论】:

    • 感谢您的详细回复!我最终决定改变应用程序结构以避免整个情况,因为我没有找到可靠的方法来决定 onDestroyActionMode 是由用户交互调用,还是由系统打开另一个动作模式。这么简单的事情变得非常棘手,因为我的应用程序有一个复杂的逻辑,有几十个嵌套的动作模式……我还是接受你的回答,因为它显示了动作模式的有趣特性。
    • 我认为这些问题已经导致许多人回避ActionMode这个危险的痛苦峡谷。但现在已经有了解决方案。
    猜你喜欢
    • 1970-01-01
    • 2011-06-08
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 2017-03-01
    • 2019-01-03
    • 1970-01-01
    相关资源
    最近更新 更多