【问题标题】:How to recognize whether the Done button is clicked in ActionMode如何识别ActionMode中是否点击了Done按钮
【发布时间】:2012-07-23 11:31:21
【问题描述】:

我使用ActionMode 来选择网格中的项目。问题是我无法识别是否准确地点击了 Done 按钮。我唯一能知道的就是ActionMode 已经完成了。但是按 Back 也会完成ActionMode。 期望的行为是在 Done 点击时接受选择,并在 Back 按下时退出 ActionMode

我尝试使用ActionMode.setCustomView(),但它不影响完成按钮。启动 ActionMode 时不会调用 Activity.onBackPressed()

我发现的一种解决方案是使用 ActionBarSherlock 并手动获取 完成 按钮:

View closeButton = findViewById(R.id.abs__action_mode_close_button); 

但它仅适用于 Android 2.x-3.x,因为在 4.x 上使用了本机操作栏。

【问题讨论】:

    标签: android android-actionbar actionbarsherlock


    【解决方案1】:

    请不要这样做,因为它是特定于实现且极其不标准的。

    您可以使用onDestroyActionMode 回调来解除操作模式。

    【讨论】:

    • 我明白了,但我正在实现一个支持多选的选择器,我认为“完成”按钮是接受选择的最佳方式......无论如何,谢谢你的回答!看来我必须添加一个菜单项来接受所选项目。
    • 但是我们如何区分完成按钮和返回按钮呢?我需要为这些人实施不同的行动......
    • 你也许可以拦截onBackPressed。否则,你不能。
    • @JakeWharton 如何区分由于屏幕旋转或完成按钮造成的 ActionMode 破坏。实际上我有一个要添加到 fav 数据库表的 id 列表,所以如果设备方向更改我应该保留这个数组,如果用户单击完成按钮我应该清除它,请帮助
    • @JakeWharton 但是这种情况如何:我有一个片段,其中包含一个列表视图,而该片段位于 ViewPager 中。点击并按住启动 CAB,按完成取消 CAB。假设我正在多选事物中(所以 CAB 处于打开状态)。当我在 ViewPager 中滑动到另一个片段时,我自然想删除 CAB,为此,我在第一个片段的 onPause 方法上完成了动作模式,当用户滑回该片段时,我再次启动 CAB。我认为我应该能够通过滑动和完成来区分解雇 CAB,以便我可以在暂停时重新启动 CAB
    【解决方案2】:

    解决办法如下:

    ActionMode mMode = MyActivityClass.this.startActionMode(some implementation);
    int doneButtonId = Resources.getSystem().getIdentifier("action_mode_close_button", "id", "android");
    View doneButton = MyActivityClass.this.findViewById(doneButtonId);
    doneButton.setOnClickListener(new View.OnClickListener() {
    
        @Override
        public void onClick(View v) {
            // do whatever you want 
            // in android source code it's calling mMode.finish();
        }
    });
    

    【讨论】:

    • 只是一个旁注:注意你调用findViewById是从你启动动作模式的Activity而不是从其他视图,否则你会得到一个null pointer exception
    • 这不适用于 Gingerbread 等前 ICS 设备上的 ABS。
    • 此代码仅适用于 API LEVEL >= 11 您需要添加 API LEVEL 条件:View doneButton; if (android.os.Build.VERSION.SDK_INT >= 11) { doneButton = Resources.getSystem().getIdentifier("action_mode_close_button", "id", "android"); } else { doneButton = findViewById(R.id.abs__action_mode_close_button); }
    • 警告:这是一个不灵活的解决方案,它本质上是访问私有 API。如果 Google 更改了 action_mode_close_button 的名称,这将停止工作。
    • 此解决方案完美运行,除非方向更改按钮失去其点击监听器。我不会破坏方向改变的活动。
    【解决方案3】:

    这是我的实现,它是一个适当的 hack,但它有效,当单击 ActionMode DONE 时,我真的找不到替代方法来执行特定的操作。我觉得你不能更优雅地捕捉这个事件真的很奇怪。

    任何使这个稍微不那么难看的建议将不胜感激......

    在我的活动中..

    boolean mActionModeIsActive = false;
    boolean mBackWasPressedInActionMode = false;
    
    @Override
    public boolean dispatchKeyEvent(KeyEvent event)
    {
        mBackWasPressedInActionMode = mActionModeIsActive && event.getKeyCode() == KeyEvent.KEYCODE_BACK;
        return super.dispatchKeyEvent(event);
    }
    
    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu)
    {
        mActionModeIsActive = true;
        return true;
    }
    
    @Override
    public void onDestroyActionMode(ActionMode mode)
    {
        mActionModeIsActive = false;
    
        if (!mBackWasPressedInActionMode)
            onActionModeDoneClick();
    
        mBackWasPressedInActionMode = false;
    }
    
    public void onActionModeDoneClick();
    {
        // Do something here.
    }
    

    如果您在 Activity 中使用 Fragments,那么其中一些代码可能需要在 Fragment 中,而其他位在 Activity 中。

    @JakeWharton(和其他 ActionBarSherlock 用户)如果您在旅途中看到这个。我很想知道以上内容是否与 ABS 兼容,因为我尚未将 ABS 与我当前的项目集成。

    【讨论】:

    • 这确实有效,但我在项目的几个地方使用了动作模式。所以我决定将 MenuItems 添加到操作模式中,并将它们用作实际的“确认”项目。主要我将图标转换为解雇。这使得代码不那么骇人听闻。
    • 看起来这也会检测到点击普通菜单项的时间,而不仅仅是按下完成按钮的时间。
    • @JDJ 是什么让你这么想?
    • 至于答案,看起来不错,但它在没有 mActionModeIsActive 的情况下也可以工作:相反,只需确保在 onCreateActionMode 中设置mBackWasPressedInActionMode = false,然后在dispatchKeyEvent 中删除&&,所以它只是第二个测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 2012-05-23
    • 2018-05-15
    相关资源
    最近更新 更多