Как отключить копирование/вставку из/в EditText
В моем приложении есть экран регистрации, где я не хочу, чтобы пользователь мог копировать/вставлять текст в поле 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 по умолчанию, у которой может быть кнопка для копирования/вставки или которая может отображать одно и то же контекстное меню. Итак, как отключить копирование/вставку в этом сценарии?
Пожалуйста, дайте мне знать, есть ли другие способы копирования и вставки. (и, возможно, как их отключить)
Любая помощь будет оценена.
Ответы
Ответ 1
Если вы используете уровень 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;
}
});
Возврат false из onCreateActionMode (ActionMode, Menu) предотвратит запуск режима действия (выберите "Все", "Вырезать", "Копировать" и "Вставить" ).
Ответ 2
Лучший способ:
etUsername.setLongClickable(false);
Ответ 3
Вы можете сделать это, отключив длительное нажатие EditText
Чтобы реализовать его, просто добавьте следующую строку в xml -
android:longClickable="false"
Ответ 4
Я могу отключить функции копирования и вставки со следующим:
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);
Надеюсь, что это сработает для вас; -)
Ответ 5
здесь лучший способ отключить вырезать скопированную копию 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;
}
});
}
Ответ 6
В дополнение к setCustomSelectionActionModeCallback и отключить длительное нажатие, необходимо препятствовать появлению меню PASTE/REPLACE при щелчке по рукописью выбора текста в соответствии с изображением ниже:
![Text selection handle with paste menu]()
Решение заключается в предотвращении появления меню PASTE/REPLACE в show()
методе (без документа) android.widget.Editor
класс. Перед появлением меню выполняется проверка на if (!canPaste && !canSuggest) return;
. Два метода, которые используются в качестве основы для установки этих переменных, находятся в классе EditText
:
Более полный ответ доступен здесь.
Ответ 7
Используя другие решения, 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) {
}
}
}
Ответ 8
Решение Kotlin:
fun TextView.disableCopyPaste() {
isLongClickable = false
setTextIsSelectable(false)
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?) {}
}
}
Затем вы можете просто вызвать этот метод на своем TextView
:
override fun onCreate() {
priceEditText.disableCopyPaste()
}
Ответ 9
Если вы не хотите отключать длительный щелчок, потому что вам нужно выполнить некоторые функции при длинном щелчке, лучше вернуть это значение.
Ваш длинный текст редактирования будет выглядеть следующим образом.
edittext.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// Do Something or Don't
return true;
}
});
Согласно документации
Возвращение "True" будет означать, что длинный щелчок был обработан, поэтому нет необходимости выполнять операции по умолчанию.
Я проверил это на уровне API 16, 22 и 25. Он отлично работает для меня. Надеюсь, это поможет.
Ответ 10
https://github.com/neopixl/PixlUI предоставляет EditText
метод
myEditText.disableCopyAndPaste()
.
И он работает на старый API
Ответ 11
Вот взломать, чтобы отключить всплывающее окно "paste". Вы должны переопределить метод EditText
:
@Override
public int getSelectionStart() {
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getMethodName().equals("canPaste")) {
return -1;
}
}
return super.getSelectionStart();
}
Аналогично можно сделать и для других действий.
Ответ 12
Прочитайте буфер обмена, проверьте на вход и время ввода "набрано". Если буфер обмена имеет один и тот же текст, и он слишком быстр, удалите вставленный ввод.
Ответ 13
@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;
}
Ответ 14
решение очень простое
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
Попробуйте следовать классу обычного для преобладающего копирования и вставки в Edittext
public class SegoeUiEditText extends AppCompatEditText {
private final Context context;
@Override
public boolean isSuggestionsEnabled() {
return false;
}
public SegoeUiEditText(Context context) {
super(context);
this.context = context;
init();
}
public SegoeUiEditText(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init();
}
public SegoeUiEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
init();
}
private void setFonts(Context context) {
this.setTypeface(Typeface.createFromAsset(context.getAssets(), "Fonts/Helvetica-Normal.ttf"));
}
private void init() {
setTextIsSelectable(false);
this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
this.setLongClickable(false);
}
@Override
public int getSelectionStart() {
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getMethodName().equals("canPaste")) {
return -1;
}
}
return super.getSelectionStart();
}
/**
* 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, android.view.ActionMode.Callback {
private final String TAG = SegoeUiEditText.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) {}
@Override
public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
menu.clear();
return false;
}
@Override
public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
return false;
}
@Override
public void onDestroyActionMode(android.view.ActionMode mode) {
}
}
}
Ответ 16
Для смартфона с буфером обмена возможно предотвратить подобное.
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;
}
}});
Ответ 17
Я проверил это решение, и это работает
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;
}
});
Ответ 18
Подобно GnrlKnowledge, вы можете очистить буфер обмена
http://developer.android.com/reference/android/text/ClipboardManager.html
Если вы хотите, сохраните текст в буфере обмена и onDestroy, вы можете установить его снова.
Ответ 19
Я обнаружил, что при создании входного фильтра во избежание ввода нежелательных символов вставка таких символов в текст редактирования не оказывает никакого эффекта. Так что этот вопрос решает и мою проблему.
Ответ 20
Вы можете попробовать андроид: focusableInTouchMode = "false".
Ответ 21
Решение, которое работало для меня, заключалось в создании пользовательского 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);
}
}
Ответ 22
Попробуй использовать.
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;
}
});