在我的应用程序中,有一个注册屏幕,我不希望用户能够将文本复制/粘贴到EditText
字段中。我在每个onLongClickListener
上设置了EditText
,因此显示复制/粘贴/输入方法和其他选项的上下文菜单不会显示。因此,用户将无法复制/粘贴到“编辑”字段中。
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默认设置之外的第三方键盘,可能有一个复制/粘贴按钮,或者可能显示相同的上下文菜单。那么如何在该场景中禁用复制/粘贴?
如果还有其他方法可以复制/粘贴,请告诉我。 (可能还有如何禁用它们)
任何帮助都将不胜感激。
答案 0 :(得分:115)
最好的方法是使用:
etUsername.setLongClickable(false);
答案 1 :(得分:104)
如果您使用的是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将阻止启动操作模式(选择全部,剪切,复制和粘贴操作)。
答案 2 :(得分:35)
您可以通过禁用长按EditText
来执行此操作要实现它,只需在xml中添加以下行 -
android:longClickable="false"
答案 3 :(得分:30)
我可以通过以下方式禁用复制和粘贴功能:
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);
希望它适合你; - )
答案 4 :(得分:12)
这是在所有版本中禁用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;
}
});
}
答案 5 :(得分:7)
除setCustomSelectionActionModeCallback和disabled long-click解决方案外,点击文字选择句柄时还需要显示prevent the PASTE/REPLACE menus,如下图所示:
解决方案在于防止PASTE / REPLACE菜单出现在(未记录的)android.widget.Editor
类的show()
方法中。在菜单出现之前,检查if (!canPaste && !canSuggest) return;
。用作设置这些变量的基础的两个方法都在EditText
类:
isSuggestionsEnabled()
为public,因此可能会被覆盖。canPaste()
不是,因此必须在派生类中由introducing a function of the same name隐藏。更完整的答案是available here。
答案 6 :(得分:6)
使用其他解决方案时,API 26(Oreo)仍然可以通过单击输入的文本来显示光标手柄,然后可以显示菜单。只有解决方案的组合才能解决我的问题。
public class CustomEditText extends EditText {
public CustomEditText(Context context) {
super(context);
init();
}
public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
this.setCustomSelectionActionModeCallback(new BlockedActionModeCallback());
this.setLongClickable(false);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
this.setInsertionDisabled();
}
return super.onTouchEvent(event);
}
/**
* This method sets TextView#Editor#mInsertionControllerEnabled field to false
* to return false from the Editor#hasInsertionController() method to PREVENT showing
* of the insertionController from EditText
* The Editor#hasInsertionController() method is called in Editor#onTouchUpEvent(MotionEvent event) method.
*/
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) {
}
}
}
答案 7 :(得分:4)
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()
}
答案 8 :(得分:4)
如果您不想禁用长按,因为您需要在长时间点击时执行某些功能而不是返回true,这样做是更好的选择。
您的edittext长按会像这样。
edittext.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// Do Something or Don't
return true;
}
});
根据documentation 返回&#34; True&#34;将表明已经处理了长按,因此无需执行默认操作。
我在API级别16,22和25上对此进行了测试。它对我来说很好。希望这会有所帮助。
答案 9 :(得分:3)
答案 10 :(得分:2)
我以 Kotlin 语言添加了扩展功能:
fun EditText.disableTextSelection() {
this.setCustomSelectionActionModeCallback(object : android.view.ActionMode.Callback {
override fun onActionItemClicked(mode: android.view.ActionMode?, item: MenuItem?): Boolean {
return false
}
override fun onCreateActionMode(mode: android.view.ActionMode?, menu: Menu?): Boolean {
return false
}
override fun onPrepareActionMode(mode: android.view.ActionMode?, menu: Menu?): Boolean {
return false
}
override fun onDestroyActionMode(mode: android.view.ActionMode?) {
}
})
}
您可以这样使用它:
edit_text.disableTextSelection()
还在xml中的行下方添加了
android:longClickable="false"
android:textIsSelectable="false"
答案 11 :(得分:2)
这是一个禁用&#34;粘贴&#34;弹出。您必须覆盖EditText
方法:
@Override
public int getSelectionStart() {
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getMethodName().equals("canPaste")) {
return -1;
}
}
return super.getSelectionStart();
}
其他行动也可以这样做。
答案 12 :(得分:1)
对于带剪贴板的智能手机,可以防止这种情况。
editText.setFilters(new InputFilter[]{new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (source.length() > 1) {
return "";
} return null;
}
}});
答案 13 :(得分:1)
尝试以下定制类,以进行优先复制并粘贴到 var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("cookie1=\(val1);cookie2=\(val2);", forHTTPHeaderField: "Cookie")
request.httpShouldHandleCookies = true
webView.loadRequest(request)
Edittext
}
答案 14 :(得分:1)
解决方案非常简单
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) {
}
});
}
}
答案 15 :(得分:1)
我已经测试了该解决方案,并且可以正常工作
mSubdomainEditText.setLongClickable(false);
mSubdomainEditText.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;
}
});
答案 16 :(得分:1)
@Zain Ali,你的答案适用于API 11.我只是想在API 10上建议一种方法。由于我必须在该版本上维护我的项目API,因此我不断使用2.3.3中提供的功能并且有可能实现它。我已经分享了下面的代码段。我测试了代码,它对我有用。我迫切需要这个片段。如果有任何可以做的更改,请随意改进代码。
// 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;
}
答案 17 :(得分:1)
阅读剪贴板,检查输入和“输入”输入的时间。如果剪贴板具有相同的文本且速度太快,请删除粘贴的输入。
答案 18 :(得分:0)
谁正在Kotlin中寻找解决方案,请使用以下类作为自定义窗口小部件,并在xml中使用它。
SecureEditText类:TextInputEditText {
/** 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 fun isSuggestionsEnabled(): Boolean {
return false
}
override fun getSelectionStart(): Int {
for (element in Thread.currentThread().stackTrace) {
if (element.methodName == "canPaste") {
return -1
}
}
return super.getSelectionStart()
}
public override fun onSelectionChanged(start: Int, end: Int) {
val text = text
if (text != null) {
if (start != text.length || end != text.length) {
setSelection(text.length, text.length)
return
}
}
super.onSelectionChanged(start, end)
}
companion object {
private val EDITTEXT_ATTRIBUTE_COPY_AND_PASTE = "isCopyPasteDisabled"
private val PACKAGE_NAME = "http://schemas.android.com/apk/res-auto"
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
disableCopyAndPaste(context, attrs)
}
/**
* Disable Copy and Paste functionality on EditText
*
* @param context Context object
* @param attrs AttributeSet Object
*/
private fun disableCopyAndPaste(context: Context, attrs: AttributeSet) {
val isDisableCopyAndPaste = attrs.getAttributeBooleanValue(
PACKAGE_NAME,
EDITTEXT_ATTRIBUTE_COPY_AND_PASTE, true
)
if (isDisableCopyAndPaste && !isInEditMode()) {
val inputMethodManager =
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
this.setLongClickable(false)
this.setOnTouchListener(BlockContextMenuTouchListener(inputMethodManager))
}
}
/**
* Perform Focus Enabling Task to the widget with the help of handler object
* with some delay
* @param inputMethodManager is used to show the key board
*/
private fun performHandlerAction(inputMethodManager: InputMethodManager) {
val postDelayedIntervalTime: Long = 25
Handler().postDelayed(Runnable {
this@SecureEditText.setSelected(true)
this@SecureEditText.requestFocusFromTouch()
inputMethodManager.showSoftInput(
this@SecureEditText,
InputMethodManager.RESULT_SHOWN
)
}, postDelayedIntervalTime)
}
/**
* Class to Block Context Menu on double Tap
* 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
*
* @param inputMethodManager is used to show the key board
*/
private inner class BlockContextMenuTouchListener internal constructor(private val inputMethodManager: InputMethodManager) :
View.OnTouchListener {
private var lastTapTime: Long = 0
val TIME_INTERVAL_BETWEEN_DOUBLE_TAP = 30
override fun onTouch(v: View, event: MotionEvent): Boolean {
if (event.getAction() === MotionEvent.ACTION_DOWN) {
val currentTapTime = System.currentTimeMillis()
if (lastTapTime != 0L && currentTapTime - lastTapTime < TIME_INTERVAL_BETWEEN_DOUBLE_TAP) {
this@SecureEditText.setSelected(false)
performHandlerAction(inputMethodManager)
return true
} else {
if (lastTapTime == 0L) {
lastTapTime = currentTapTime
} else {
lastTapTime = 0
}
performHandlerAction(inputMethodManager)
return true
}
} else if (event.getAction() === MotionEvent.ACTION_MOVE) {
this@SecureEditText.setSelected(false)
performHandlerAction(inputMethodManager)
}
return false
}
}
}
答案 19 :(得分:0)
如果要禁用.png
进行复制/粘贴,则需要覆盖2个回调。这适用于ActionMode
和TextView
(或EditText
)
TextInputEditText
此扩展程序基于@Alexandr解决方案,对我来说效果很好。
答案 20 :(得分:0)
广泛兼容的解决方案(从 Android 1.5 开始)是
@Override
public boolean onTextContextMenuItem(int id) {
switch (id){
case android.R.id.cut:
onTextCut();
return false;
case android.R.id.paste:
onTextPaste();
return false;
case android.R.id.copy:
onTextCopy();
return false;
}
return true;
}
答案 21 :(得分:0)
尝试使用。
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;
}
});
答案 22 :(得分:0)
对我有用的解决方案是创建自定义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);
}
}
答案 23 :(得分:0)
您可以尝试android:focusableInTouchMode =“false”。
答案 24 :(得分:0)
我发现当您创建输入过滤器以避免输入不需要的字符时,将这些字符粘贴到编辑文本中是没有效果的。所以这种方式也解决了我的问题。
答案 25 :(得分:0)
与GnrlKnowledge类似,您可以清除剪贴板
http://developer.android.com/reference/android/text/ClipboardManager.html
如果需要,保留剪贴板中的文本,在onDestroy上,您可以再次设置它。