Android 运行时确定的小写 EditText 数据条目
Android EditText data entry in lowercase determined at runtime
我很惊讶这不是 EditText
的本机函数,但我找不到任何机制可以在输入到 EditText
字段时将输入转换为小写. EditText
字段决定了运行时是否为小写,所以我不能在 XML 中有这个,它需要在我分配 EditText
时触发。我试过:
1) 取消全部大写:
mEntry.setInputType(InputType.TYPE_CLASS_TEXT | ~InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
2) 创建监听器:
private TextWatcher textWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!Utilities.stringIsBlank(mField.getFormat()) && Field.LOWER.equalsIgnoreCase(mField.getFormat())) {
if (!Utilities.stringIsBlank(s.toString()) && !s.toString().equals(s.toString().toLowerCase()) ) {
mEntry.setText(s.toString().toLowerCase());
mEntry.setSelection(start+1);
}
}
}
}
问题在于,当我调用 setText()
时,它递归地回调到 onTextChange
事件,这会扰乱光标的位置,具体取决于光标的变化。
有人有我不知何故遗漏的简单解决方案吗?
像这样检查 if 语句中的文本
if(mEntry.getText().toString().equals( mEntry.getText().toString().toLowerCase() )
return;
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!Utilities.stringIsBlank(mField.getFormat()) && Field.LOWER.equalsIgnoreCase(mField.getFormat())) {
if (!Utilities.stringIsBlank(s.toString()) && !s.toString().equals(s.toString().toLowerCase()) ) {
if (mEntry.getText().toString().equals(mEntry.getText().toString().toLowerCase())return;
mEntry.setText(s.toString().toLowerCase());
mEntry.setSelection(start+1);
}
}
}
您可以使用过滤器。下面是修改后的 AllCaps filter,将所有内容都转换为小写而不是大写。
/**
* This filter will lower case all the capitalized letters that are added
* through edits.
*/
public static class NoCapsFilter implements InputFilter {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (Character.isUpperCase(source.charAt(i))) {
char[] v = new char[end - start];
TextUtils.getChars(source, start, end, v, 0);
String s = new String(v).toLowerCase();
if (source instanceof Spanned) {
SpannableString sp = new SpannableString(s);
TextUtils.copySpansFrom((Spanned) source,
start, end, null, sp, 0);
return sp;
}
else {
return s;
}
}
}
return null; // keep original
}
}
然后只需在 EditText
上设置过滤器即可。
mEntry.setFilters(new InputFilter[]{new NoCapsFilter()});
我很惊讶这不是 EditText
的本机函数,但我找不到任何机制可以在输入到 EditText
字段时将输入转换为小写. EditText
字段决定了运行时是否为小写,所以我不能在 XML 中有这个,它需要在我分配 EditText
时触发。我试过:
1) 取消全部大写:
mEntry.setInputType(InputType.TYPE_CLASS_TEXT | ~InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
2) 创建监听器:
private TextWatcher textWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!Utilities.stringIsBlank(mField.getFormat()) && Field.LOWER.equalsIgnoreCase(mField.getFormat())) {
if (!Utilities.stringIsBlank(s.toString()) && !s.toString().equals(s.toString().toLowerCase()) ) {
mEntry.setText(s.toString().toLowerCase());
mEntry.setSelection(start+1);
}
}
}
}
问题在于,当我调用 setText()
时,它递归地回调到 onTextChange
事件,这会扰乱光标的位置,具体取决于光标的变化。
有人有我不知何故遗漏的简单解决方案吗?
像这样检查 if 语句中的文本
if(mEntry.getText().toString().equals( mEntry.getText().toString().toLowerCase() )
return;
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!Utilities.stringIsBlank(mField.getFormat()) && Field.LOWER.equalsIgnoreCase(mField.getFormat())) {
if (!Utilities.stringIsBlank(s.toString()) && !s.toString().equals(s.toString().toLowerCase()) ) {
if (mEntry.getText().toString().equals(mEntry.getText().toString().toLowerCase())return;
mEntry.setText(s.toString().toLowerCase());
mEntry.setSelection(start+1);
}
}
}
您可以使用过滤器。下面是修改后的 AllCaps filter,将所有内容都转换为小写而不是大写。
/**
* This filter will lower case all the capitalized letters that are added
* through edits.
*/
public static class NoCapsFilter implements InputFilter {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (Character.isUpperCase(source.charAt(i))) {
char[] v = new char[end - start];
TextUtils.getChars(source, start, end, v, 0);
String s = new String(v).toLowerCase();
if (source instanceof Spanned) {
SpannableString sp = new SpannableString(s);
TextUtils.copySpansFrom((Spanned) source,
start, end, null, sp, 0);
return sp;
}
else {
return s;
}
}
}
return null; // keep original
}
}
然后只需在 EditText
上设置过滤器即可。
mEntry.setFilters(new InputFilter[]{new NoCapsFilter()});