Reputation: 2790
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??
Upvotes: 11
Views: 38336
Reputation: 66989
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) {
}
});
Upvotes: 7
Reputation: 11
you should trim the text.
spannable.setSpan(
ForegroundColorSpan(textColor),
FIRST_INDEX, someText.trim().length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Upvotes: 1
Reputation: 539
just add one more space to your string and then
mEditPass.setSelection(new string);
Upvotes: 0
Reputation: 6307
The Error says you are ending the spanable text before its start, look for any character that you gave to end and its appearing before start
Upvotes: 1
Reputation: 2790
This problem was fixed by adding next code:
mEditPass.getText().clearSpans();
before
mEditPass.getText().clear();
Upvotes: 2