Android перехват вставитькопироватьвырезать на editText
как я могу перехватить такого рода событий ?
мне нужно добавить некоторую логику, когда пользователь пытается вставить текст в мой EditText
Я знаю, что могу использовать TextWatcher
но это entrypoint не хорошо для меня, потому что мне нужно только перехватить в случае вставки и не каждый раз, когда пользователь нажимает my EditText
,
2 ответов
кажется, что вы мало что можете сделать с помощью API:событие вставки android
я зарылся в источник Android TextView
(EditText
это TextView
С некоторой другой конфигурацией) и узнал, что меню, используемое для предложения параметров вырезать/копировать/вставить, является просто измененным ContextMenu
(источник).
как для обычного контекстного меню, представление должно создать меню (источник), а затем обрабатывать взаимодействие в методе обратного вызова (источник).
потому что метод обработки является public
, мы можем просто подключиться к нему, расширяя EditText
и перезапись метода для реагирования на различные действия. Вот пример реализации:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.EditText;
import android.widget.Toast;
/**
* An EditText, which notifies when something was cut/copied/pasted inside it.
* @author Lukas Knuth
* @version 1.0
*/
public class MonitoringEditText extends EditText {
private final Context context;
/*
Just the constructors to create a new EditText...
*/
public MonitoringEditText(Context context) {
super(context);
this.context = context;
}
public MonitoringEditText(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public MonitoringEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
}
/**
* <p>This is where the "magic" happens.</p>
* <p>The menu used to cut/copy/paste is a normal ContextMenu, which allows us to
* overwrite the consuming method and react on the different events.</p>
* @see <a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3_r1/android/widget/TextView.java#TextView.onTextContextMenuItem%28int%29">Original Implementation</a>
*/
@Override
public boolean onTextContextMenuItem(int id) {
// Do your thing:
boolean consumed = super.onTextContextMenuItem(id);
// React:
switch (id){
case android.R.id.cut:
onTextCut();
break;
case android.R.id.paste:
onTextPaste();
break;
case android.R.id.copy:
onTextCopy();
}
return consumed;
}
/**
* Text was cut from this EditText.
*/
public void onTextCut(){
Toast.makeText(context, "Cut!", Toast.LENGTH_SHORT).show();
}
/**
* Text was copied from this EditText.
*/
public void onTextCopy(){
Toast.makeText(context, "Copy!", Toast.LENGTH_SHORT).show();
}
/**
* Text was pasted into the EditText.
*/
public void onTextPaste(){
Toast.makeText(context, "Paste!", Toast.LENGTH_SHORT).show();
}
}
теперь, когда пользователь использует cut/copy / paste, a Toast
показано (конечно, вы могли бы сделать и другие вещи).
в аккуратная вещь, что это работает вплоть до Android 1.5 и вам не нужно повторно создавать контекстное меню (как предложено в приведенном выше связанном вопросе), которое будет держите постоянный вид платформы (например, с HTC Sense).
есть гораздо более простой способ, хотя и не 100% Надежный.
добавить TextChangedListener в поле редактирования:
EditText et = (EditText) mView.findViewById(R.id.yourEditText);
et.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (count > 2) toast("text was pasted");
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void afterTextChanged(Editable s) {
}
});
Если текст изменяется более чем на 2 символа, вы можете предположить, что он был вставлен (некоторые смайлики занимают два символа).
конечно, он не обнаружит вставку, когда пользователь вставляет 1 или два символа, и он будет ложно сообщать о вставке, если изменение текста было вызвано чем-то другим.
но для большинства целей это делает свою работу.