【问题标题】:Android Remove CAB menu from textView Custom Selection Action ModeAndroid 从 textView 自定义选择操作模式中删除 CAB 菜单
【发布时间】:2018-04-03 10:10:27
【问题描述】:

我通过此代码添加了一个自定义上下文菜单。

ns_text_menu.xml 只包含两项。

this.textViewTest.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {

                menu.clear();

                mode.setTitle("Menu");
                mode.getMenuInflater().inflate(R.menu.ns_text_menu, menu);

                return true;
            }

            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false;
            }

            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {

                if (item.getTitle().equals("View Vocab")) {

                    ErrorController.showToast(mContext, "View Vocab : " + textViewTest.getText().toString().substring(textViewTest.getSelectionStart(), textViewTest.getSelectionEnd()));

                }else{//cpy
                    ErrorController.showToast(mContext, "Copy : " + textViewTest.getSelectionStart() + ", " + textViewTest.getSelectionEnd());

                }

                return true;
            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {

            }
        });

正如这个答案(Remove default CAB items in TextView selection ActionMode)中提到的,我使用了代码

menu.clear();

在 onCreateActionMode 上清除默认 CAB 菜单。它清除了一些默认的上下文菜单,但仍然保留了这两个菜单:

“全选”和“字典”。

测试机是galaxy s9+(android 8.0),nexus模拟器(6.0)。

它们都显示了意想不到的菜单。

我该如何解决这个问题?

【问题讨论】:

    标签: android textview


    【解决方案1】:

    onPrepareActionMode 上似乎添加了意想不到的菜单。

    为了解决这个问题,

    (1) 将我的自定义菜单的 ID 存储在全局列表中。 (2)在onPrepareActionMode中,删除所有与上面列表中存储的ids不匹配的菜单。

    代码如下所示。

    this.textViewTest.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
    
                private List<Integer> validResIdList = new ArrayList<>();
    
                @Override
                public boolean onCreateActionMode(ActionMode mode, Menu menu) {
    
    
                    menu.clear();
                    validResIdList.clear();
    
                    mode.getMenuInflater().inflate(R.menu.ns_text_menu, menu);
    
                    for (int i = 0; i < menu.size(); i++) {
    
                        validResIdList.add(menu.getItem(i).getItemId());
                    }
    
                    return true;
                }
    
                @Override
                public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
    
    
                    List<Integer> toRemoveResId = new ArrayList<>();
    
                    for (int i = 0; i < menu.size(); i++) {
    
                        if (menu.getItem(i).getItemId() != (validResIdList.get(0)) && menu.getItem(i).getItemId() != (validResIdList.get(1))) {
    
                            toRemoveResId.add(menu.getItem(i).getItemId());
                        }
                    }
    
                    for (Integer resId : toRemoveResId) {
                        menu.removeItem(resId);
                    }
    
                    return true;
                }
    
                @Override
                public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
    
                    if(validResIdList != null && validResIdList.size() > 0){
    
                        if (item.getItemId() == validResIdList.get(0)) {
    
                            ErrorController.showToast(mContext, "View Vocab : " + textViewTest.getText().toString().substring(textViewTest.getSelectionStart(), textViewTest.getSelectionEnd()));
                            mode.finish();
    
                        } else {//cpy
                            ErrorController.showToast(mContext, "Copy : " + textViewTest.getSelectionStart() + ", " + textViewTest.getSelectionEnd());
                            mode.finish();
                        }
                    }
    
                    return true;
                }
    
                @Override
                public void onDestroyActionMode(ActionMode mode) {
    
                }
            });
    

    我在 R.id.xxx 上使用 validResIdList 的原因是因为我在一个库项目中实现它。

    如果您在一个应用程序项目中,您可以使用 R.id.xxx 来确定您正在处理的菜单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-13
      相关资源
      最近更新 更多