我想提出一个垂直EditText
传统蒙古。 我已经成功地通过嵌入略加修改实现了它EditText
一个旋转的内部ViewGroup
。 我需要创建一个完全自定义的快捷菜单,因为系统中的一个不支持垂直文本;当也没有转动ViewGroup
旋转。 所以我想完全禁用系统的上下文菜单。
请注意,这是比这些问题,这只是试图禁用复制/粘贴/等不同:
- 如何禁用复制/粘贴/到的EditText
- EditText上:禁止粘贴/替换菜单弹出的文本选择处理程序click事件
- 如何禁用的Android EditText上粘贴选项
- 安卓:如何TOTALLY禁止复制和粘贴功能EDITTEXT
虽然我没有得到上下文菜单中出现的模拟器,我把它在我的Android 5.0.2小蜜手机出现。
我试过了:
- 该
setCustomSelectionActionModeCallback
“解决方案” - 所述
setLongClickable(false);
“解” - 在
onTouchEvent
“解决方案”
我打开黑客,但我需要它在任何设备上工作。 马克·墨菲(下议院人) 写了一段时间,早在回答其他用户试图做同样的事情:
我怀疑,即使你想出一个答案,它不会跨设备使用。 设备制造商不得不打滚的EditText自己的“上下文菜单”的倾向,击败开发者试图将项目添加到该上下文菜单。 我的猜测是,试图阻止上下文菜单中都会有类似的结果。
难道我的运气?
我现在能想到的唯一的事情是完全重写TextView
和EditText
从头开始(当然,通过修改Android的源)。 我知道别人谁做了类似的事情,但他的代码是不是开源。 之前我借此大步,我想试着问这里一个简单的解决方案堆栈溢出。
更新:我一直在试图修改TextView
源代码,在过去的两天,它看起来像一个6个月的项目。 这是相互关联的类的质量。 我需要另一种解决方案,但我的想法。
MVCE
这是我能想到的重现问题的最简单方法。 有没有必要从我的自定义EditText
。 布局有一个单一EditText
通过更换默认的项目你好世界作出TextView
。 我改变了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罗伊的解决方案是工作在模拟器上,他已经测试了一些其他的设备,我的设备上。 我已经接受了他的答案,因为它解决了我原来的问题。 唯一的负面副作用是文本的选择也将被禁用。
Answer 1:
有你需要做三件事情。
步骤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。
STEP 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) {
}
}
}
Answer 2:
我已经为这个代码EditText
,而且对这一问题工作的罚款。
try {
edtName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
edtName.setSelection(0);
}
});
edtName.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return true;
}
});
edtName.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) { }
});
} catch (Exception e) {
e.printStackTrace();
}
Answer 3:
解决的方法很简单
public class MainActivity extends AppCompatActivity {
EditText et_0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_0 = findViewById(R.id.et_0);
et_0.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//to keep the text selection capability available ( selection cursor)
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
//to prevent the menu from appearing
menu.clear();
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
});
}
}
Answer 4:
mEditText.setLongClickable(false);
它禁用编辑文本的最简单方法。
Answer 5:
这是怎么出现在任何方式,形状或形式阻止复制粘贴菜单。 这个错误真的让我抓狂,而且与任何三星的bug,你在他们的代码知道它,但你也知道,他们不会很快修复它的任何时间。 不管怎么说,这里的奇迹墙...
检查Android.Build.Model.toLowerCase()。startsWith( 'SM-G930')。 不要将整个字符串匹配,最后一个字母是次要版本标识符。 我保存这个布尔在shouldBlockCopyPaste变量后来出现。
如果匹配要从显示阻止复制粘贴菜单。 这是你如何真正做到这一点!
覆盖这些2个功能,你会发现我的shouldBlockCopyPaste布尔,这是如此的其他设备不被阻塞。
@Override
public ActionMode StartActionMode (ActionMode.Callback callback){
if (shouldBlockCopyPaste) {
return null;
} else {
return super.StartActionMode(callback);
}
}
@Override
public ActionMode StartActionMode (ActionMode.Callback callback, int type){
if (shouldBlockCopyPaste) {
return null;
} else {
return super.StartActionMode(callback, type);
}
}
Answer 6:
试试这个
mEditText.setClickable(false);
mEditText.setEnabled(false);
UPDATE
通过扩展EDITTEXT尝试这种解决方案,
import android.content.Context;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
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) {}
}
}
参考: https://stackoverflow.com/a/28893714/5870896
文章来源: Disable EditText context menu