我有一个扩展MyEditText
的课程EditText
。
当从InputMethodService接收特定的密钥代码时,比如35 {等于'#'
,我想要执行一个操作
我的EditText而不是将其附加到文本。
无效的解决方案:
设置onEditorActionListener
无效,因为onEditAction()
仅针对KeyEvent.KEYCODE_ENTER
等特定代码集调用,我需要检测接收代码的事件超出那一套。
设置onKeyListener。这也没有用,但我不知道原因,我甚至不确定这个听众是为了这个目的。这是我尝试过的代码,输入时不会记录任何内容:
edittext.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.d("EDITOR_TAG", "onKey()");
return false;
}
});
修改:在进一步测试后,onKey()
也会调用KeyEvent.KEYCODE_ENTER
,但不会调用其他密钥代码。就像onEditorAction()
。
可能有效的解决方法,但我更愿意避免:实施beforeTextChanged()
接口的onTextChanged()
,afterTextChanged()
和TextWatcher
。
我想避免这种情况的原因是它会干扰这些方法中实现的历史机制(对于undo / redo)。
我想在更改文本之前使用接收密钥代码35的事件。
答案 0 :(得分:0)
试试这个包装类,希望它能解决你的问题:
public class CustomEditText extends EditText {
public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomEditText(Context context) {
super(context);
}
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
if (lengthBefore < lengthAfter) {
char c = text.charAt(start + lengthAfter - 1);
if (c == '#') {
char[] newChars = new char[text.length() - 1];
for (int i = 0, j = 0; i < text.length(); i++) {
if (i != (start + lengthAfter - 1))
newChars[j++] = text.charAt(i);
}
setText(new String(newChars));
}
}
}
}
根据我的说法,如果没有TextWatcher,我没有找到任何直接的方法。但是我找到了一个解决方法,它工作正常,但根据您的自定义要求,几乎不需要修改。
希望它对您有用:)
答案 1 :(得分:0)
我正面临同样的挑战,并提出了解决方案。 只需将以下类复制粘贴到您的项目中:
OnTextChangedListener.class
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;
public class OnTextChangedListener implements TextWatcher {
private static final String TAG = OnTextChangedListener.class.getSimpleName();
private boolean isManualChange = false;
private EditText mEditText;
private char[] consumeChars;
public OnTextChangedListener(char[] consumeChars, EditText editText){
mEditText = editText;
if(consumeChars == null){
this.consumeChars = new char[0];
} else{
this.consumeChars = consumeChars;
}
}
public OnTextChangedListener(){
this.consumeChars = new char[0];
}
@Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
String newString = charSequence.toString();
if(containsConsumeChar(newString)){
newString = removeConsumeChars(newString);
int cursorPos = mEditText.getSelectionStart(); // or getSelectionEnd() doesn't matter
isManualChange = true;
mEditText.setText(newString);
int maxPos = newString.length();
mEditText.setSelection(cursorPos > maxPos ? maxPos : cursorPos);
} else if(before != count && !isManualChange){
Log.d(TAG, "Text (actually) changed!");
String text = charSequence.toString();
// calls your own implementation if you have one
onTextActuallyChanged(text, start, before, count);
} else{
Log.d(TAG, "consumed manual change");
isManualChange = false;
}
}
@Override
public void afterTextChanged(Editable editable) {
}
public void onTextActuallyChanged(String newText, int start, int lengthBefore, int lengthNow){
}
public void onCharacterConsumed(char consumed){
}
private boolean containsConsumeChar(String text){
for(char c : consumeChars){
if(text.contains(""+c)) return true;
}
return false;
}
private String removeConsumeChars(String text){
for(char c : consumeChars){
if(text.contains(""+c)){
Log.d(TAG, "consumed all '" + c + "'s");
text = text.replaceAll(""+c, "");
// calls your own implementation if you have one
onCharacterConsumed(c);
}
}
return text;
}
}
用法:
OnTextChangedListener consumeThis = new OnTextChangedListener(new char[]{'#'}, myEditText);
myEditText.addTextChangedListener(consumeThis);
或
myEditText.addTextChangedListener(new OnTextChangedListener(new char['#'], myEditText){
@Override
public void onCharacterConsumed(char consumed) {
// TODO: implement your magic here
}
});