如何禁用从/到EditText复制/粘贴
在我的应用程序中,有一个注册屏幕,我不希望用户能够将文本复制/粘贴到EditText
字段中。 我已经在每个EditText
上设置了onLongClickListener
,以便显示复制/粘贴/input方法和其他选项的上下文菜单不显示。 所以用户将无法复制/粘贴到编辑字段。
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默认键盘以外的其他第三方键盘,则可能会出现问题,可能会有一个复制/粘贴button或可能显示相同的上下文菜单。 那么我如何禁用复制/粘贴在这种情况下?
请让我知道是否有其他方法来复制/粘贴。 (并可能如何禁用它们)
任何帮助,将不胜感激。
如果您使用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);
我可以通过以下方式禁用复制粘贴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长按来做到这一点
要实现它,只需在xml中添加以下行:
android:longClickable="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和禁用的长按解决scheme之外,还需要防止在单击文本select句柄时出现PASTE / REPLACE菜单 ,如下图所示:
解决scheme在于防止PASTE / REPLACE菜单出现在(未logging的) android.widget.Editor
类的show()
方法中。 在菜单出现之前,检查if (!canPaste && !canSuggest) return;
。 作为设置这些variables的基础的两个方法都在EditText
类中:
-
isSuggestionsEnabled()
是公共的 ,因此可以被覆盖。 -
canPaste()
不是,因此必须通过在派生类中引入相同名称的函数来隐藏。
更完整的答案可以在这里find 。
阅读剪贴板,检查input和input“键入”的时间。 如果剪贴板文本相同且速度太快,请删除粘贴的input。
@Zain Ali,你的答案在API 11上工作。我只是想build议一种在API 10上做的方法。 由于我必须在该版本上维护我的项目API,所以我一直在玩2.3.3中提供的function,并有可能做到这一点。 我已经分享下面的代码片段。 我testing了代码,它为我工作。 我紧急地做了这个片段。 如果有任何可以改变的地方,请随意改进代码。
// 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(); }
对于其他行为也可以做类似的事情。
与GnrlKnowledge类似,您可以清除剪贴板
http://developer.android.com/reference/android/text/ClipboardManager.html
如果需要,请保留剪贴板中的文本,然后在onDestroy上重新设置。
我发现当你创build一个inputfilter来避免input不需要的字符时,将这些字符粘贴到编辑文本中是没有任何作用的。 所以这样也解决了我的问题。
你可以尝试android:focusableInTouchMode =“false”。
我工作的解决scheme是创build自定义的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); }
}
Kotlin解决scheme:
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() }
如果你不想禁止长时间点击,因为你需要长时间执行一些function而不是返回true,这是一个更好的select。
你的edittext长按就会是这样的。
edittext.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { // Do Something or Don't return true; } });
根据文档返回“True”将表示长按已被处理,因此不需要执行默认操作。
我在API级别16,22和25上testing了它。它对我来说工作得很好。 希望这会有所帮助。