I am using this library for material editText with label: https://github.com/rey5137/Material/wiki/Text-Field nice library :)
but...
i am using next code to check are entered symbols correct:
private boolean hasCorrectSymbols(String input){
String tre = "[A-Za-z0-9\\@\\#\\$\\%\\&\\*\\(\\)\\-\\+\\_\\;\\:\\?\\.\\,\\!]+$";
if (input.matches(tre)){
return true;
}
return false;
}
for checking correct symbols I am using textWatcher:
mEditPass.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() == 1 && !loginPassHasCorrectSymbols(s.toString())){
mEditPass.getText().clear();
String mess = getString(R.string.toast_login_useLatin);
showToastMessage(mess);
} else if (s.length() >1 && !loginPassHasCorrectSymbols(s.toString())) {
String mess = getString(R.string.toast_login_useLatin);
showToastMessage(mess);
String text = s.toString();
text = text.substring(0, start);
mEditPass.setText(text);
mEditPass.setSelection(start);
}
}
@Override
public void afterTextChanged(Editable s) {}
});
if first symbol is correct and the second one for example is wrong - system will cut last entered (wrong) symbol and set cursor to the last text position, but if the first symbol is prohibited symbol - it will crash with this error:
java.lang.IndexOutOfBoundsException: setSpan (0 ... 1) ends beyond length 0
at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1016)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:592)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:588)
at android.text.method.PasswordTransformationMethod.onTextChanged(PasswordTransformationMethod.java:108)
at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:962)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:496)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:435)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:30)
at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:683)
at android.view.inputmethod.BaseInputConnection.commitText(BaseInputConnection.java:198)
at com.android.internal.widget.EditableInputConnection.commitText(EditableInputConnection.java:183)
at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:279)
at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5097)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Any ideas why it happen? And how to fix this??
In this code snippet, you shorten the text displayed in the EditText
(so that the last valid position is start-1
), but still try to set the selection position to start
.
text = text.substring(0, start);
mEditPass.setText(text);
mEditPass.setSelection(start);
[EDITED]
Assuming that your Toast message is prompting the user to fix the error, I think what you actually want to do is to set the selection to the first character in the EditText with a bad symbol. Here is sample code for doing that:
// A reusable Pattern (at the class level) that defines the regex for bad characters.
private static final Pattern ILLEGAL_CHAR_PATTERN = Pattern.compile(
"[^A-Za-z0-9\\@\\#\\$\\%\\&\\*\\(\\)\\-\\+\\_\\;\\:\\?\\.\\,\\!]"
);
// Replacement for your listener code.
mEditPass.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() == 0 || count == 0) {
return;
}
Matcher matcher = ILLEGAL_CHAR_PATTERN.matcher(s);
if (matcher.find()) {
int firstIllegalPos = matcher.start();
mEditPass.setSelection(firstIllegalPos);
String mess = getString(R.string.toast_login_useLatin);
showToastMessage(mess);
}
}
@Override
public void afterTextChanged(Editable s) {
}
});