当我将InputFilter
与TextWatcher
合并时,我发现了一种奇怪的行为。
我基本上想要做的是帮助用户键入MAC地址。首先,我想在用户输入的每两个字符中添加一个分隔符(“:”)。
代码与我的香草Nexus 7一样正常工作,但是我的LG Optimus 4X HD(足够公平,它上面有一个夜间的Cyanogenmod),还有三星Galaxy S4的股票,有一种奇怪的行为。
我将标识为EditText
的{{1}}添加到空的项目和布局中,并将以下代码添加到我的活动中(自动生成的函数未复制):
editText1
}
我按下mutliple buttoms添加一些字符,然后尝试删除所有字符。 Nexus 7的日志(应该是):
public class MainActivity extends Activity {
private static final String LOG_TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText et = (EditText) this.findViewById(R.id.editText1);
et.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
et.addTextChangedListener(new TestTextWatcher());
InputFilter[] inFi = { new InputFilter.LengthFilter(17),
new TestInputFilter() };
et.getText().setFilters(inFi);
}
private static class TestTextWatcher implements TextWatcher {
private static final String regExp = "..(:..){5}";
private static final Pattern pat = Pattern.compile(regExp);
@Override
public void afterTextChanged(Editable s) {
Log.d(LOG_TAG, "AFTERTEXTCHANGED: " + s.toString());
Matcher m = pat.matcher(s);
// if does not match regexp
if (!m.matches() && !m.hitEnd()) {
SpannableStringBuilder ssb = new SpannableStringBuilder(s);
Log.d(LOG_TAG, "remove " + ssb.toString());
for (int i = 0; i < ssb.length(); i++) {
char c = ssb.charAt(i);
if (c == ':') {
ssb.delete(i, i + 1);
i--; // recheck same position
}
}
Log.d(LOG_TAG, "insert " + ssb.toString());
for (int i = 2; i < ssb.length(); i = i + 3) {
ssb.insert(i, ":");
Log.d(LOG_TAG, "Inserting: " + i + " " + ssb.toString());
}
Log.d(LOG_TAG, "trunc " + ssb.toString());
if (ssb.length() > 17) {
ssb.delete(17, ssb.length());
}
Log.d(LOG_TAG, "replace " + ssb.toString());
s.replace(0, s.length(), ssb);
}
}
}
private static class TestInputFilter implements InputFilter {
@Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
Log.d(LOG_TAG, "FILTER: source: " + source.toString() + " dest: "
+ dest.toString());
// if character is deleted do nothing
if (end - start == 0) {
return null;
}
StringBuilder sb = new StringBuilder(dest.toString());
sb.replace(dstart, dend, source.toString().substring(start, end));
if ((sb.length() - 2) % 3 == 0 && sb.length() < 17) {
SpannableStringBuilder sourceAsSpannableBuilder = new SpannableStringBuilder(
source);
sourceAsSpannableBuilder = (SpannableStringBuilder) sourceAsSpannableBuilder
.subSequence(start, end);
sourceAsSpannableBuilder.append(":");
Log.d(LOG_TAG, "filter, spannable " + sourceAsSpannableBuilder.toString());
return sourceAsSpannableBuilder;
}
return null;
}
}
LG的输出:
10-12 17:18:36.336: D/MainActivity(9535): FILTER: source: s dest:
10-12 17:18:36.336: D/MainActivity(9535): AFTERTEXTCHANGED: s
10-12 17:18:38.088: D/MainActivity(9535): FILTER: source: s dest: s
10-12 17:18:38.088: D/MainActivity(9535): filter, spannable s:
10-12 17:18:38.088: D/MainActivity(9535): AFTERTEXTCHANGED: ss:
10-12 17:18:38.508: D/MainActivity(9535): FILTER: source: s dest: ss:
10-12 17:18:38.508: D/MainActivity(9535): AFTERTEXTCHANGED: ss:s
10-12 17:18:38.778: D/MainActivity(9535): FILTER: source: s dest: ss:s
10-12 17:18:38.778: D/MainActivity(9535): filter, spannable s:
10-12 17:18:38.778: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:
10-12 17:18:39.079: D/MainActivity(9535): FILTER: source: s dest: ss:ss:
10-12 17:18:39.079: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:s
10-12 17:18:39.309: D/MainActivity(9535): FILTER: source: s dest: ss:ss:s
10-12 17:18:39.309: D/MainActivity(9535): filter, spannable s:
10-12 17:18:39.309: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:
10-12 17:18:39.539: D/MainActivity(9535): FILTER: source: s dest: ss:ss:ss:
10-12 17:18:39.539: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:s
10-12 17:18:39.729: D/MainActivity(9535): FILTER: source: s dest: ss:ss:ss:s
10-12 17:18:39.729: D/MainActivity(9535): filter, spannable s:
10-12 17:18:39.729: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:ss:
10-12 17:18:39.930: D/MainActivity(9535): FILTER: source: s dest: ss:ss:ss:ss:
10-12 17:18:39.940: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:ss:s
10-12 17:18:40.120: D/MainActivity(9535): FILTER: source: s dest: ss:ss:ss:ss:s
10-12 17:18:40.120: D/MainActivity(9535): filter, spannable s:
10-12 17:18:40.120: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:ss:ss:
10-12 17:18:40.330: D/MainActivity(9535): FILTER: source: s dest: ss:ss:ss:ss:ss:
10-12 17:18:40.330: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:ss:ss:s
10-12 17:18:40.630: D/MainActivity(9535): FILTER: source: s dest: ss:ss:ss:ss:ss:s
10-12 17:18:40.630: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:ss:ss:ss
10-12 17:18:40.931: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss:ss:ss:ss
10-12 17:18:41.241: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss:ss:ss:ss
10-12 17:18:42.582: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss:ss:ss:ss
10-12 17:18:42.582: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:ss:ss:s
10-12 17:18:42.772: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss:ss:ss:s
10-12 17:18:42.772: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:ss:ss:
10-12 17:18:42.943: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss:ss:ss:
10-12 17:18:42.953: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:ss:ss
10-12 17:18:43.123: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss:ss:ss
10-12 17:18:43.123: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:ss:s
10-12 17:18:43.283: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss:ss:s
10-12 17:18:43.283: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:ss:
10-12 17:18:43.473: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss:ss:
10-12 17:18:43.473: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:ss
10-12 17:18:43.623: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss:ss
10-12 17:18:43.623: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:s
10-12 17:18:43.793: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss:s
10-12 17:18:43.793: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss:
10-12 17:18:43.974: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss:
10-12 17:18:43.974: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:ss
10-12 17:18:44.144: D/MainActivity(9535): FILTER: source: dest: ss:ss:ss
10-12 17:18:44.144: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:s
10-12 17:18:44.314: D/MainActivity(9535): FILTER: source: dest: ss:ss:s
10-12 17:18:44.314: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss:
10-12 17:18:44.484: D/MainActivity(9535): FILTER: source: dest: ss:ss:
10-12 17:18:44.484: D/MainActivity(9535): AFTERTEXTCHANGED: ss:ss
10-12 17:18:44.644: D/MainActivity(9535): FILTER: source: dest: ss:ss
10-12 17:18:44.644: D/MainActivity(9535): AFTERTEXTCHANGED: ss:s
10-12 17:18:44.814: D/MainActivity(9535): FILTER: source: dest: ss:s
10-12 17:18:44.814: D/MainActivity(9535): AFTERTEXTCHANGED: ss:
10-12 17:18:44.985: D/MainActivity(9535): FILTER: source: dest: ss:
10-12 17:18:44.995: D/MainActivity(9535): AFTERTEXTCHANGED: ss
10-12 17:18:45.125: D/MainActivity(9535): FILTER: source: dest: ss
10-12 17:18:45.125: D/MainActivity(9535): AFTERTEXTCHANGED: s
10-12 17:18:45.305: D/MainActivity(9535): FILTER: source: dest: s
10-12 17:18:45.305: D/MainActivity(9535): AFTERTEXTCHANGED:
10-12 17:18:45.445: D/MainActivity(9535): FILTER: source: dest:
我无法删除最后一个符号(“aa:”),因为没有调用afterTextChanged或filter。如果我移动光标并添加字符,我可以将其删除:
10-12 17:28:54.280: D/MainActivity(15778): FILTER: source: a dest:
10-12 17:28:54.280: D/MainActivity(15778): AFTERTEXTCHANGED: a
10-12 17:28:54.680: D/MainActivity(15778): FILTER: source: a dest: a
10-12 17:28:54.690: D/MainActivity(15778): filter, spannable a:
10-12 17:28:54.690: D/MainActivity(15778): AFTERTEXTCHANGED: aa:
10-12 17:28:55.140: D/MainActivity(15778): FILTER: source: a dest: aa:
10-12 17:28:55.140: D/MainActivity(15778): AFTERTEXTCHANGED: aa:a
10-12 17:28:55.570: D/MainActivity(15778): FILTER: source: a dest: aa:a
10-12 17:28:55.570: D/MainActivity(15778): filter, spannable a:
10-12 17:28:55.570: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:
10-12 17:28:55.870: D/MainActivity(15778): FILTER: source: a dest: aa:aa:
10-12 17:28:55.870: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:a
10-12 17:28:56.140: D/MainActivity(15778): FILTER: source: a dest: aa:aa:a
10-12 17:28:56.140: D/MainActivity(15778): filter, spannable a:
10-12 17:28:56.140: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:
10-12 17:28:56.390: D/MainActivity(15778): FILTER: source: a dest: aa:aa:aa:
10-12 17:28:56.390: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:a
10-12 17:28:56.720: D/MainActivity(15778): FILTER: source: a dest: aa:aa:aa:a
10-12 17:28:56.720: D/MainActivity(15778): filter, spannable a:
10-12 17:28:56.730: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:aa:
10-12 17:28:56.960: D/MainActivity(15778): FILTER: source: a dest: aa:aa:aa:aa:
10-12 17:28:56.960: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:aa:a
10-12 17:28:57.210: D/MainActivity(15778): FILTER: source: a dest: aa:aa:aa:aa:a
10-12 17:28:57.210: D/MainActivity(15778): filter, spannable a:
10-12 17:28:57.210: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:aa:aa:
10-12 17:28:57.460: D/MainActivity(15778): FILTER: source: a dest: aa:aa:aa:aa:aa:
10-12 17:28:57.460: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:aa:aa:a
10-12 17:28:57.740: D/MainActivity(15778): FILTER: source: a dest: aa:aa:aa:aa:aa:a
10-12 17:28:57.740: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:aa:aa:aa
10-12 17:28:58.040: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa:aa:aa:aa
10-12 17:28:58.380: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa:aa:aa:aa
10-12 17:28:59.160: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa:aa:aa:aa
10-12 17:28:59.160: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:aa:aa:a
10-12 17:28:59.360: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa:aa:aa:a
10-12 17:28:59.360: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:aa:aa:
10-12 17:28:59.530: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa:aa:aa:
10-12 17:28:59.530: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:aa:aa
10-12 17:28:59.680: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa:aa:aa
10-12 17:28:59.680: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:aa:a
10-12 17:28:59.830: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa:aa:a
10-12 17:28:59.830: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:aa:
10-12 17:28:59.970: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa:aa:
10-12 17:28:59.970: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:aa
10-12 17:29:00.100: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa:aa
10-12 17:29:00.100: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:a
10-12 17:29:00.280: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa:a
10-12 17:29:00.280: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa:
10-12 17:29:00.410: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa:
10-12 17:29:00.410: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:aa
10-12 17:29:00.550: D/MainActivity(15778): FILTER: source: dest: aa:aa:aa
10-12 17:29:00.550: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:a
10-12 17:29:00.700: D/MainActivity(15778): FILTER: source: dest: aa:aa:a
10-12 17:29:00.700: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:
10-12 17:29:00.860: D/MainActivity(15778): FILTER: source: dest: aa:aa:
10-12 17:29:00.860: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa
10-12 17:29:01.000: D/MainActivity(15778): FILTER: source: dest: aa:aa
10-12 17:29:01.000: D/MainActivity(15778): AFTERTEXTCHANGED: aa:a
10-12 17:29:01.150: D/MainActivity(15778): FILTER: source: dest: aa:a
10-12 17:29:01.150: D/MainActivity(15778): AFTERTEXTCHANGED: aa:
Galaxy S4表现得更奇怪: 如果我按下ONE键,当添加了第一个分隔符时,它会添加所有写入的字符和按下的键:
10-12 17:30:13.600: D/MainActivity(15778): FILTER: source: a dest: aa:
10-12 17:30:13.610: D/MainActivity(15778): AFTERTEXTCHANGED: aaa:
10-12 17:30:13.610: D/MainActivity(15778): remove aaa:
10-12 17:30:13.610: D/MainActivity(15778): insert aaa
10-12 17:30:13.610: D/MainActivity(15778): Inserting: 2 aa:a
10-12 17:30:13.610: D/MainActivity(15778): trunc aa:a
10-12 17:30:13.610: D/MainActivity(15778): replace aa:a
10-12 17:30:13.610: D/MainActivity(15778): FILTER: source: aa:a dest: aaa:
10-12 17:30:13.610: D/MainActivity(15778): AFTERTEXTCHANGED: aa:a
10-12 17:30:13.940: D/MainActivity(15778): FILTER: source: a dest: aa:a
10-12 17:30:13.940: D/MainActivity(15778): filter, spannable a:
10-12 17:30:13.940: D/MainActivity(15778): AFTERTEXTCHANGED: aaa::a
10-12 17:30:13.940: D/MainActivity(15778): remove aaa::a
10-12 17:30:13.940: D/MainActivity(15778): insert aaaa
10-12 17:30:13.940: D/MainActivity(15778): Inserting: 2 aa:aa
10-12 17:30:13.940: D/MainActivity(15778): trunc aa:aa
10-12 17:30:13.940: D/MainActivity(15778): replace aa:aa
10-12 17:30:13.940: D/MainActivity(15778): FILTER: source: aa:aa dest: aaa::a
10-12 17:30:13.940: D/MainActivity(15778): filter, spannable aa:aa:
10-12 17:30:13.940: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa:
10-12 17:30:15.270: D/MainActivity(15778): FILTER: source: dest: aa:aa:
10-12 17:30:15.280: D/MainActivity(15778): AFTERTEXTCHANGED: aa:aa
10-12 17:30:15.460: D/MainActivity(15778): FILTER: source: dest: aa:aa
10-12 17:30:15.460: D/MainActivity(15778): AFTERTEXTCHANGED: aa:a
10-12 17:30:15.630: D/MainActivity(15778): FILTER: source: dest: aa:a
10-12 17:30:15.630: D/MainActivity(15778): AFTERTEXTCHANGED: aa:
10-12 17:30:15.810: D/MainActivity(15778): FILTER: source: dest: aa:
10-12 17:30:15.810: D/MainActivity(15778): AFTERTEXTCHANGED: aa
10-12 17:30:15.970: D/MainActivity(15778): FILTER: source: dest: aa
10-12 17:30:15.970: D/MainActivity(15778): AFTERTEXTCHANGED: a
10-12 17:30:16.150: D/MainActivity(15778): FILTER: source: dest: a
10-12 17:30:16.150: D/MainActivity(15778): AFTERTEXTCHANGED:
我错过了什么吗?我是否使用了一个糟糕的“黑客”女巫在Nexus上工作,但在其他手机上却没有? 或者基本上:为什么机器人的行为不同以及如何防止这种情况?
问候,
Fhnx
PS:很抱歉长篇文章。