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

在我的应用程序中,有一个注册屏幕,我不希望用户能够将文本复制/粘贴到EditText字段中。 我已经在每个EditText上设置了onLongClickListener ,以便显示复制/粘贴/输入方法和其他选项的上下文菜单不显示。 所以用户将无法复制/粘贴到编辑字段。

  OnLongClickListener mOnLongClickListener = new OnLongClickListener() { @Override public boolean onLongClick(View v) { // prevent context menu from being popped up, so that user // cannot copy/paste from/into any EditText fields. return true; } }; 

但是,如果用户启用了Android默认键盘以外的其他第三方键盘,则可能会出现问题,该键盘可能有一个复制/粘贴按钮或可能显示相同的上下文菜单。 那么我如何禁用复制/粘贴在这种情况下?

请让我知道是否有其他方法来复制/粘贴。 (并可能如何禁用它们)

任何帮助,将不胜感激。

如果您使用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将阻止启动操作模式(全选,剪切,复制和粘贴操作)。

最好的方法是使用:

 etUsername.setLongClickable(false); 

您可以通过禁用EditText长按来做到这一点

要实现它,只需在xml中添加以下行:

 android:longClickable="false" 

我可以通过以下方式禁用复制粘贴function:

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

希望对你有帮助 ;-)

这里是禁用所有版本的editText工作剪切粘贴的最佳方法

 if (android.os.Build.VERSION.SDK_INT < 11) { editText.setOnCreateContextMenuListener(new OnCreateContextMenuListener() { @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { // TODO Auto-generated method stub menu.clear(); } }); } else { editText.setCustomSelectionActionModeCallback(new ActionMode.Callback() { public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // TODO Auto-generated method stub return false; } public void onDestroyActionMode(ActionMode mode) { // TODO Auto-generated method stub } public boolean onCreateActionMode(ActionMode mode, Menu menu) { // TODO Auto-generated method stub return false; } public boolean onActionItemClicked(ActionMode mode, MenuItem item) { // TODO Auto-generated method stub return false; } }); } 

除了setCustomSelectionActionModeCallback和禁用的长按解决方案之外,还需要防止在单击文本选择句柄时出现PASTE / REPLACE菜单 ,如下图所示:

文本选择句柄与粘贴菜单

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

  • isSuggestionsEnabled()是公共的 ,因此可以被覆盖。
  • canPaste()不是,因此必须通过在派生类中引入同名函数来隐藏。

更完整的答案可以在这里find 。

https://github.com/neopixl/PixlUI提供了一个EditText和一个方法

myEditText.disableCopyAndPaste()

它在旧的API上工作

阅读剪贴板,检查输入和输入“键入”的时间。 如果剪贴板文本相同且速度太快,请删除粘贴的输入。

@Zain Ali,你的答案在API 11上工作。我只是想提出一个在API 10上做的方法。 由于我必须在该版本上维护我的项目API,所以我一直在玩2.3.3中提供的function,并有可能做到这一点。 我已经分享下面的代码片段。 我测试了代码,它为我工作。 我紧急地做了这个片段。 如果有任何可以改变的地方,请随意改进代码。

 // A custom TouchListener is being implemented which will clear out the focus // and gain the focus for the EditText, in few milliseconds so the selection // will be cleared and hence the copy paste option wil not pop up. // the respective EditText should be set with this listener // tmpEditText.setOnTouchListener(new MyTouchListener(tmpEditText, tmpImm)); public class MyTouchListener implements View.OnTouchListener { long click = 0; EditText mEtView; InputMethodManager imm; public MyTouchListener(EditText etView, InputMethodManager im) { mEtView = etView; imm = im; } @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { long curr = System.currentTimeMillis(); if (click !=0 && ( curr - click) < 30) { mEtView.setSelected(false); new Handler().postDelayed(new Runnable() { @Override public void run() { mEtView.setSelected(true); mEtView.requestFocusFromTouch(); imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN); } },25); return true; } else { if (click == 0) click = curr; else click = 0; new Handler().postDelayed(new Runnable() { @Override public void run() { mEtView.requestFocusFromTouch(); mEtView.requestFocusFromTouch(); imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN); } },25); return true; } } else if (event.getAction() == MotionEvent.ACTION_MOVE) { mEtView.setSelected(false); new Handler().postDelayed(new Runnable() { @Override public void run() { mEtView.setSelected(true); mEtView.requestFocusFromTouch(); mEtView.requestFocusFromTouch(); imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN); } },25); return true; } return false; } 

这是一个黑客来禁用“粘贴”popup。 你必须重写EditText方法:

 @Override public int getSelectionStart() { for (StackTraceElement element : Thread.currentThread().getStackTrace()) { if (element.getMethodName().equals("canPaste")) { return -1; } } return super.getSelectionStart(); } 

对于其他行为也可以做类似的事情。

Kotlin解决方案:

 fun TextView.disableCopyPaste() { customSelectionActionModeCallback = object : ActionMode.Callback { override fun onCreateActionMode(mode: ActionMode?, menu: Menu): Boolean { return false } override fun onPrepareActionMode(mode: ActionMode?, menu: Menu): Boolean { return false } override fun onActionItemClicked(mode: ActionMode?, item: MenuItem): Boolean { return false } override fun onDestroyActionMode(mode: ActionMode?) {} } isLongClickable = false setTextIsSelectable(false) } 

那么你可以简单地在你的TextView上调用这个方法:

 override fun onCreate() { priceEditText.disableCopyPaste() } 

尝试使用。

 myEditext.setCursorVisible(false); myEditext.setCustomSelectionActionModeCallback(new ActionMode.Callback() { public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // TODO Auto-generated method stub return false; } public void onDestroyActionMode(ActionMode mode) { // TODO Auto-generated method stub } public boolean onCreateActionMode(ActionMode mode, Menu menu) { // TODO Auto-generated method stub return false; } public boolean onActionItemClicked(ActionMode mode, MenuItem item) { // TODO Auto-generated method stub return false; } }); 

与GnrlKnowledge类似,您可以清除剪贴板

http://developer.android.com/reference/android/text/ClipboardManager.html

如果需要,请保留剪贴板中的文本,然后在onDestroy上重新设置。

我发现当你创建一个输入filter来避免输入不需要的字符时,将这些字符粘贴到编辑文本中是没有任何作用的。 所以这样也解决了我的问题。

你可以尝试android:focusableInTouchMode =“false”。

我工作的解决方案是创建自定义的EditText并重写以下方法:

 public class MyEditText extends EditText { private int mPreviousCursorPosition; @Override protected void onSelectionChanged(int selStart, int selEnd) { CharSequence text = getText(); if (text != null) { if (selStart != selEnd) { setSelection(mPreviousCursorPosition, mPreviousCursorPosition); return; } } mPreviousCursorPosition = selStart; super.onSelectionChanged(selStart, selEnd); } 

}

如果你不想禁止长时间点击,因为你需要长时间执行一些function而不是返回true,这是一个更好的选择。

你的edittext长按就会是这样的。

 edittext.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { // Do Something or Don't return true; } }); 

根据文档返回“True”将表示长按已被处理,因此不需要执行默认操作。

我在API级别16,22和25上测试了它。它对我来说工作得很好。 希望这会有所帮助。