我正在EditText
为传统的蒙古人做垂直.我通过EditText
在旋转的内部嵌入一个略微修改的内容来成功实现它ViewGroup
.我需要创建一个完全自定义的上下文菜单,因为系统不支持垂直文本,并且在旋转时也不会ViewGroup
旋转.所以我想完全禁用系统上下文菜单.
请注意,这与仅仅尝试禁用复制/粘贴/等的这些问题不同:
如何禁用从/到EditText的复制/粘贴
EditText:在文本选择处理程序单击事件上禁用粘贴/替换菜单弹出窗口
如何在android EditText中禁用粘贴选项
Android:如何在Edittext中完全禁用复制和粘贴功能
虽然我没有在模拟器中出现上下文菜单,但我将它出现在我的Android 5.0.2小米手机中.
我试过了:
在setCustomSelectionActionModeCallback
"解决方案"
在setLongClickable(false);
"解决方案"
在onTouchEvent
"解决方案"
我对hacks持开放态度,但我需要它能够在各种设备上持续工作.马克·墨菲(下议院人)写了一段时间,早在回答其他用户试图做同样的事情:
我怀疑,即使你拿出一个答案,它也无法在各种设备上运行.设备制造商倾向于为EditText推出自己的"上下文菜单",从而使开发人员尝试将项目添加到该上下文菜单中.我的猜测是,试图阻止该上下文菜单会产生类似的结果.
我运气不好吗?
我现在唯一能想到的就是完全重写TextView
并EditText
从头开始(好吧,通过修改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
您可以通过从这些方法返回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) { } } }