【问题标题】:How to disable "copy/cut/paste/" toolbar in editText, but still have cursor to select some text?如何在editText中禁用“复制/剪切/粘贴/”工具栏,但仍有光标选择一些文本?
【发布时间】:2016-01-29 20:56:16
【问题描述】:

我一直在寻找这个问题的解决方案,所以我决定在这里问它。

我正在写记事本应用,点击“new note”选项后,出现新的Activity,如下所示:

由于我的应用程序概念允许用户通过格式文本菜单(在屏幕底部可见)编辑文本,我希望允许用户选择文本,而不在 底部和复制/剪切/粘贴菜单上显示键盘。通过切换按钮访问键盘(在 2 行代码上运行良好)

当焦点通过以下代码设置在 EditText 上时,我已禁用键盘弹出:

public static void disableSoftInputFromAppearing(EditText editText) {
    if (Build.VERSION.SDK_INT >= 11) {
        editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
        editText.setTextIsSelectable(true);
    } else {
        editText.setRawInputType(InputType.TYPE_NULL);
        editText.setFocusable(true);
    }
}

应用工具栏上的键盘按钮调用的方法:

public void toggleKeyboard(MenuItem item) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
}

我想选择文本(通过双击文本或长按来实现),但主要问题是复制/剪切/粘贴工具栏,因为它覆盖了我的应用工具栏:

这就是为什么我想摆脱这个工具栏,但仍然可以选择特定的文本范围。

附:手机型号:HTC One M7

任何帮助将不胜感激

最好的问候, 汤姆

【问题讨论】:

    标签: java android


    【解决方案1】:

    对于 API 级别 11 或更高版本,您可以阻止复制、粘贴、剪切和自定义上下文菜单的出现。

    edittext.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
    
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false;
            }
    
            public void onDestroyActionMode(ActionMode mode) {                  
            }
    
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                return false;
            }
    
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                return false;
            }
        });
    

    从 onCreateActionMode(ActionMode, Menu) 返回 false 将阻止启动操作模式(全选、剪切、复制和粘贴操作)。 原回答HERE

    解决方案:覆盖 isSuggestionsEnabled 并可以在 EditText 中粘贴。

    对于快速解决方案,请复制下面的类 - 该类覆盖 EditText 类,并相应地阻止所有事件。

    有关坚韧不拔的细节,请继续阅读。

    解决方案在于防止 PASTE/REPLACE 菜单出现在(未记录的)android.widget.Editor 类的 show() 方法中。在菜单出现之前,检查 if (!canPaste && !canSuggest) return;。作为设置这些变量的基础的两个方法都在 EditText 类中:

    isSuggestionsEnabled() 是公开的,因此可以被覆盖。 canPaste() 不是,因此必须通过在派生类中引入同名函数来隐藏。 因此,将这些更新合并到一个还具有setCustomSelectionActionModeCallback 和禁用长单击的类中,这是一个完整的类,以防止所有编辑(但仍显示文本选择处理程序)以控制光标:

    package com.cjbs.widgets;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.ActionMode;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.EditText;
    
    
    /**
     *  This is a thin veneer over EditText, with copy/paste/spell-check removed.
     */
    public class NoMenuEditText extends EditText
    
    {
        private final Context context;
    
        /** This is a replacement method for the base TextView class' method of the same name. This 
         * method is used in hidden class android.widget.Editor to determine whether the PASTE/REPLACE popup
         * appears when triggered from the text insertion handle. Returning false forces this window
         * to never appear.
         * @return false
         */
        boolean canPaste()
        {
           return false;
        }
    
        /** This is a replacement method for the base TextView class' method of the same name. This method
         * is used in hidden class android.widget.Editor to determine whether the PASTE/REPLACE popup
         * appears when triggered from the text insertion handle. Returning false forces this window
         * to never appear.
         * @return false
         */
        @Override
        public boolean isSuggestionsEnabled()
        {
            return false;
        }
    
        public NoMenuEditText(Context context)
        {
            super(context);
            this.context = context;
            init();
        }
    
        public NoMenuEditText(Context context, AttributeSet attrs)
        {
            super(context, attrs);
            this.context = context;
            init();
        }
    
        public NoMenuEditText(Context context, AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
            this.context = context;
            init();
        }
    
        private void init()
        {
            this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
            this.setLongClickable(false);
        }
    
    
        /**
         * Prevents the action bar (top horizontal bar with cut, copy, paste, etc.) from appearing
         * by intercepting the callback that would cause it to be created, and returning false.
         */
        private class ActionModeCallbackInterceptor implements ActionMode.Callback
        {
            private final String TAG = NoMenuEditText.class.getSimpleName();
    
            public boolean onCreateActionMode(ActionMode mode, Menu menu) { return false; }
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; }
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; }
            public void onDestroyActionMode(ActionMode mode) {}
        }
    } 
    

    原回答HERE2

    【讨论】:

    • 我之前尝试过这个解决方案。它防止出现自定义上下文菜单,但它也禁用选择文本按钮。我有一个光标,但我不能“分离这个光标”来选择选择文本的开始和结束节点。
    • 您的下一个解决方案与第一个解决方案相同。我进行了一些研究并且注意到,实际上可以在手机处于水平方向模式时选择文本。当我在水平模式下打开键盘时,editText 是我唯一能看到的(键盘除外)。光标将颜色从应用默认更改为系统默认,这真的很奇怪。我想我需要找到另一个解决方案,也许我会为复制/粘贴工具栏腾出空间。无论如何,谢谢你的帮助,我真的很感激:)
    猜你喜欢
    • 2018-01-19
    • 2014-03-21
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 2021-03-18
    相关资源
    最近更新 更多