How to disable copy/paste from/to EditText
In my application, there is a registration screen, where i do not want the user to be able to copy/paste text into the EditText
поле. I have set an onLongClickListener
на каждой EditText
so that the context menu showing copy/paste/inputmethod and other options does not show up. So the user won't be able to copy/ paste into the Edit fields.
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 по умолчанию, которая может иметь кнопку для копирования / вставки или которая может отображать то же контекстное меню. Так как же отключить копирование / вставку в этом сценарии?
Пожалуйста, дайте мне знать, если есть и другие способы копирования / вставки. (и, возможно, как их отключить)
Любая помощь будет оценена.
32 ответа
Если вы используете 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) предотвратит запуск режима действия (действия "Выбрать все", "Вырезать", "Копировать" и "Вставить").
Лучший метод заключается в использовании:
etUsername.setLongClickable(false);
Вы можете сделать это, отключив долгое нажатие EditText
Чтобы реализовать это, просто добавьте следующую строку в xml -
android:longClickable="false"
Я могу отключить функцию копирования и вставки с помощью следующего:
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);
Надеюсь, это работает для вас;-)
Котлин раствор:
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()
}
Вот лучший способ отключить вырезать копировать вставить текст 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 в show()
метод (недокументированный) android.widget.Editor
учебный класс. Прежде чем появится меню, выполняется проверка if (!canPaste && !canSuggest) return;
, Два метода, которые используются в качестве основы для установки этих переменных, находятся в EditText
учебный класс:
isSuggestionsEnabled()
является общедоступным и, таким образом, может быть переопределено.canPaste()
не является, и, следовательно, должен быть скрыт, введя функцию с тем же именем в производном классе.
Более полный ответ доступен здесь.
Используя другие решения, 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) {
}
}
}
Если вы не хотите отключать длинный щелчок, потому что вам нужно выполнить некоторые функции при длинном щелчке, лучше выбрать вариант возврата true.
Ваш длинный текст редактирования будет таким.
edittext.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// Do Something or Don't
return true;
}
});
В соответствии с документацией, возвращение "True" будет означать, что длинный щелчок был обработан, поэтому нет необходимости выполнять операции по умолчанию.
Я проверил это на уровне API 16, 22 и 25. Он отлично работает для меня. Надеюсь, это поможет.
Вот взломать, чтобы отключить "вставить" всплывающее окно. Вы должны переопределить EditText
метод:
@Override
public int getSelectionStart() {
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getMethodName().equals("canPaste")) {
return -1;
}
}
return super.getSelectionStart();
}
Подобное можно сделать для других действий.
Я добавил функцию расширения на языке 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"
Я протестировал это решение, и оно работает
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;
}
});
https://github.com/neopixl/PixlUI предоставляет EditText
с методом
myEditText.disableCopyAndPaste()
,
И это работает на старом API
это очень поздно, но может это поможет кому-то.
добавьте эти строки в свой edittext xml
android:longClickable="false"
android:textIsSelectable="false"
android:importantForAutofill="no"
Если вы хотите отключить
ActionMode
для копирования / вставки вам нужно переопределить 2 обратных вызова. Это работает как для
TextView
и
EditText
(или же
TextInputEditText
)
import android.view.ActionMode
fun TextView.disableCopyPaste() {
isLongClickable = false
setTextIsSelectable(false)
customSelectionActionModeCallback = object : ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode?, menu: Menu) = false
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu) = false
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem) = false
override fun onDestroyActionMode(mode: ActionMode?) {}
}
//disable action mode when edittext gain focus at first
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
customInsertionActionModeCallback = object : ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode?, menu: Menu) = false
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu) = false
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem) = false
override fun onDestroyActionMode(mode: ActionMode?) {}
}
}
}
Это расширение основано на вышеупомянутом решении @Alexandr и отлично сработало для меня.
@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;
}
Для смартфона с буфером обмена возможно предотвратить подобное.
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;
}
}});
Прочитайте буфер обмена, проверьте ввод и время, когда ввод "напечатан". Если в буфере обмена тот же текст, и он слишком быстрый, удалите вставленный ввод.
Попробуйте следовать классу обычного для преобладающего копирования и вставки в 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) {
}
}
}
На самом деле в моем случае мне пришлось установить обратный вызов как для выбора , так и для вставки , и только тогда всплывающее окно копирования/вставки больше не появлялось. Что-то вроде этого :
private void disableCopyPaste() {
input.setLongClickable(false);
input.setTextIsSelectable(false);
final ActionMode.Callback disableCopyPasteCallback = 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) {
}
};
input.setCustomSelectionActionModeCallback(disableCopyPasteCallback);
input.setCustomInsertionActionModeCallback(disableCopyPasteCallback);
}
Приведенные выше решения не учитывают вставку с помощью аппаратных клавиатур (Ctrl+v). Самое простое решение — установить TextWatcher в вашем EditText и отфильтровать символы, которые вы хотите или не хотите, в методе afterTextChanged. Это работает для всех ситуаций, т. е. для набранных символов, вставок, автоматических предложений и автоматических исправлений.
Вместо того, чтобы полностью отключать все действия в EditText, вы можете запретить только определенные действия (например, вырезать/копировать, но не вставлять):
/**
* Prevent copy/cut of the (presumably sensitive) contents of this TextView.
*/
fun TextView.disableCopyCut() {
setCustomSelectionActionModeCallback(
object : Callback {
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?) = false
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
menu?.apply {
removeItem(android.R.id.copy)
removeItem(android.R.id.cut)
}
return true
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
override fun onDestroyActionMode(mode: ActionMode?) {
// no-op
}
}
)
}
Действия, которые можно выборочно удалить:
removeItem(android.R.id.copy)
removeItem(android.R.id.cut)
removeItem(android.R.id.paste)
removeItem(android.R.id.shareText) // Share
removeItem(android.R.id.textAssist) // Open with Chrome
Решение очень простое
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) {
}
});
}
}
Потратив много времени, удалив опцию вставки в ContextMenu в EditText, я выполнил приведенный ниже код на Java.
NoMenuEditText.Java
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import androidx.appcompat.widget.AppCompatEditText;
/**
* custom edit text
*/
public class NoMenuEditText extends AppCompatEditText {
private static final String EDITTEXT_ATTRIBUTE_COPY_AND_PASTE = "isCopyPasteDisabled";
private static final String PACKAGE_NAME = "http://schemas.android.com/apk/res-auto";
public NoMenuEditText(Context context) {
super(context);
}
public NoMenuEditText(Context context, AttributeSet attrs) {
super(context, attrs);
EnableDisableCopyAndPaste(context, attrs);
}
/**
* Enable/Disable Copy and Paste functionality on EditText
*
* @param context Context object
* @param attrs AttributeSet Object
*/
private void EnableDisableCopyAndPaste(Context context, AttributeSet attrs) {
boolean isDisableCopyAndPaste = attrs.getAttributeBooleanValue(PACKAGE_NAME,
EDITTEXT_ATTRIBUTE_COPY_AND_PASTE, false);
if (isDisableCopyAndPaste && !isInEditMode()) {
InputMethodManager inputMethodManager = (InputMethodManager)
context.getSystemService(Context.INPUT_METHOD_SERVICE);
this.setLongClickable(false);
this.setOnTouchListener(new BlockContextMenuTouchListener
(inputMethodManager));
}
}
/**
* Perform Focus Enabling Task to the widget with the help of handler object
* with some delay
*/
private void performHandlerAction(final InputMethodManager inputMethodManager) {
int postDelayedIntervalTime = 25;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
NoMenuEditText.this.setSelected(true);
NoMenuEditText.this.requestFocusFromTouch();
inputMethodManager.showSoftInput(NoMenuEditText.this,
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
*/
private class BlockContextMenuTouchListener implements View.OnTouchListener {
private static final int TIME_INTERVAL_BETWEEN_DOUBLE_TAP = 30;
private InputMethodManager inputMethodManager;
private long lastTapTime = 0;
BlockContextMenuTouchListener(InputMethodManager inputMethodManager) {
this.inputMethodManager = inputMethodManager;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
long currentTapTime = System.currentTimeMillis();
if (lastTapTime != 0 && (currentTapTime - lastTapTime)
< TIME_INTERVAL_BETWEEN_DOUBLE_TAP) {
NoMenuEditText.this.setSelected(false);
performHandlerAction(inputMethodManager);
return true;
} else {
if (lastTapTime == 0) {
lastTapTime = currentTapTime;
} else {
lastTapTime = 0;
}
performHandlerAction(inputMethodManager);
return true;
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
NoMenuEditText.this.setSelected(false);
performHandlerAction(inputMethodManager);
}
return false;
}
}
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
CharSequence text = getText();
if (text != null) {
if (selStart != text.length() || selEnd != text.length()) {
setSelection(text.length(), text.length());
return;
}
}
super.onSelectionChanged(selStart, selEnd);
}
@Override
public boolean isSuggestionsEnabled() {
return false;
}
@Override
public int getSelectionStart() {
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getMethodName().equals("canPaste")) {
return -1;
}
}
return super.getSelectionStart();
}
}
Основная деятельность
import androidx.appcompat.app.AppCompatActivity;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends AppCompatActivity {
NoMenuEditText edt_username;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edt_username = (NoMenuEditText) findViewById(R.id.edt_username);
edt_username.setLongClickable(false);
edt_username.setTextIsSelectable(false);
edt_username.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) {
}
});
}
}
drawable- zeropx.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="0dp"
android:height="0dp"/>
</shape>
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="NoMenuEditText">
<attr name="isCopyPasteDisabled" format="boolean" />
</declare-styleable>
</resources>
Наконец, я наконец Убрана опция вставки из контекстного меню из EditText
Спасибо за сообщения StackOverflow и http://androidinformative.com/disables-context-menu/
Кто ищет решение в Kotlin, используйте приведенный ниже класс в качестве настраиваемого виджета и используйте его в xml.
class 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
}
}
}
Я обнаружил, что когда вы создаете фильтр ввода, чтобы избежать ввода нежелательных символов, вставка таких символов в текст редактирования не оказывает никакого влияния. Так что этот вид решает и мою проблему.
Широко совместимое решение (начиная с 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;
}
editText.apply {
setOnTouchListener { v, event ->
requestFocus()
setSelection(text.toString().length)
showKeyboard()
return@setOnTouchListener true
}
}
fun View.showKeyboard() {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(this, 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;
}
});
Решение, которое работало для меня, состояло в том, чтобы создать собственный 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);
}
}