当前位置:  开发笔记 > 后端 > 正文

禁用EditText上下文菜单

如何解决《禁用EditText上下文菜单》经验,为你挑选了1个好方法。

我正在EditText为传统的蒙古人做垂直.我通过EditText在旋转的内部嵌入一​​个略微修改的内容来成功实现它ViewGroup.我需要创建一个完全自定义的上下文菜单,因为系统不支持垂直文本,并且在旋转时也不会ViewGroup旋转.所以我想完全禁用系统上下文菜单.

请注意,这与仅仅尝试禁用复制/粘贴/等的这些问题不同:

如何禁用从/到EditText的复制/粘贴

EditText:在文本选择处理程序单击事件上禁用粘贴/替换菜单弹出窗口

如何在android EditText中禁用粘贴选项

Android:如何在Edittext中完全禁用复制和粘贴功能

虽然我没有在模拟器中出现上下文菜单,但我将它出现在我的Android 5.0.2小米手机中.

我试过了:

setCustomSelectionActionModeCallback"解决方案"

setLongClickable(false);"解决方案"

onTouchEvent"解决方案"

我对hacks持开放态度,但我需要它能够在各种设备上持续工作.马克·墨菲(下议院人)写了一段时间,早在回答其他用户试图做同样的事情:

我怀疑,即使你拿出一个答案,它也无法在各种设备上运行.设备制造商倾向于为EditText推出自己的"上下文菜单",从而使开发人员尝试将项目添加到该上下文菜单中.我的猜测是,试图阻止该上下文菜单会产生类似的结果.

我运气不好吗?

我现在唯一能想到的就是完全重写TextViewEditText从头开始(好吧,通过修改Android源代码).我知道其他人做了类似的事,但他的代码不是开源的.在我采取这一重大步骤之前,我想尝试在Stack Overflow上寻求更简单的解决方案.

更新:我一直在尝试修改TextView过去两天的源代码,看起来像是一个6个月的项目.这是一大堆相互关联的课程.我需要另一种解决方案,但我没有想法.

MVCE

这是我能想到的最简单的方法来重现问题.我的习惯没有必要EditText.布局有一个EditText替换默认项目Hello World的TextView.我将min API更改为11以避免处理已弃用的方法.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText editText = (EditText) findViewById(R.id.edit_text);
        editText.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
            @Override
            public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { return false; }
            @Override
            public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) { return false; }
            @Override
            public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) { return false; }
            @Override
            public void onDestroyActionMode(ActionMode actionMode) { }
        });
    }
}

模拟器(运行API 24)中的上下文菜单仍然显示我单击光标手柄(但不是长按或双击).这是一张图片:

在此输入图像描述

在运行Android 5.0的小米MIUI手机上,我得到了所有情况下的上下文菜单(光标处理单击,长按,双击).

更新

Aritra Roy的解决方案是在模拟器中,在他测试的其他设备上以及我的设备上工作.我接受了他的答案,因为它解决了我原来的问题.唯一的负面影响是文本选择也被禁用​​.



1> Aritra Roy..:

你需要做三件事.

步骤1

您可以通过从这些方法返回false来禁用显示的上下文菜单,

mEditEext.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;
            }
        });

第2步

有必要禁用EditText中的长按.

mEditText.setLongClickable(false);

android:longClickable="false"以XML格式执行此操作.

第3步

现在,您需要防止在单击手柄时出现菜单.解决方案很简单,

1)扩展EditText课程,

2)覆盖isSuggestionsEnabled()并返回false,

3)创建一个canPaste()方法并返回false.这是方法隐藏.

快速解决方案

如果您不想手动完成所有这些操作.这是一个自定义的EditText类,您可以使用它来快速完成此操作.但我仍然建议你一次完成这些步骤,以了解事情是如何运作的.

public class MenuHidingEditText extends EditText {
    private final Context mContext;

    public MenuHidingEditText(Context context) {
        super(context);
        this.mContext = context;

        blockContextMenu();
    }

    public MenuHidingEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;

        blockContextMenu();
    }

    public MenuHidingEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.mContext = context;

        blockContextMenu();
    }

    private void blockContextMenu() {
        this.setCustomSelectionActionModeCallback(new BlockedActionModeCallback());
        this.setLongClickable(false);
        this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                MenuHidingEditText.this.clearFocus();
                return false;
            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // setInsertionDisabled when user touches the view
            this.setInsertionDisabled();
        }
        return super.onTouchEvent(event);
    }

    private void setInsertionDisabled() {
        try {
            Field editorField = TextView.class.getDeclaredField("mEditor");
            editorField.setAccessible(true);
            Object editorObject = editorField.get(this);

            Class editorClass = Class.forName("android.widget.Editor");
            Field mInsertionControllerEnabledField = editorClass.getDeclaredField("mInsertionControllerEnabled");
            mInsertionControllerEnabledField.setAccessible(true);
            mInsertionControllerEnabledField.set(editorObject, false);
        }
        catch (Exception ignored) {
            // ignore exception here
        }
    }

    @Override
    public boolean isSuggestionsEnabled() {
        return false;
    }

    private class BlockedActionModeCallback implements ActionMode.Callback {

        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) {
        }
    }
}

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有