Apparently, this and this are the same problems that I am having, though my Textview is an AutoCompleteTextView. I am selecting from my contacts list. Whenever I make a selection, I get the following error:
java.lang.IllegalArgumentException: Invalid offset: -1. Valid range is [0, 23] at android.text.method.WordIterator.checkOffsetIsValid(WordIterator.java:384) at android.text.method.WordIterator.preceding(WordIterator.java:72) at android.widget.SpellChecker$SpellParser.parse(SpellChecker.java:599) at android.widget.SpellChecker$SpellParser.parse(SpellChecker.java:517) at android.widget.SpellChecker.spellCheck(SpellChecker.java:242) at android.widget.Editor.updateSpellCheckSpans(Editor.java:707) at android.widget.Editor.sendOnTextChanged(Editor.java:1256) at android.widget.TextView.sendOnTextChanged(TextView.java:9368) at android.widget.TextView.setText(TextView.java:5397) at android.widget.TextView.setText(TextView.java:5250) at android.widget.EditText.setText(EditText.java:113) at com.webnation.text2email.widgets.AutoCompleteContactTextView$2.onItemClick(AutoCompleteContactTextView.java:183)
Which seems to be coming from the cursor being selected outside of the allowed bounds. The workarounds given in the above link do not seem to be helping. This is where the crash happens:
public class AutoCompleteContactTextView extends AppCompatAutoCompleteTextView implements CustomAdapter.AsyncLoad {
private void init(Context context, AttributeSet attrs, boolean programmatic) {
this.context = context;
this.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 (AutoCompleteContactTextView.this.getAdapter() != null && !s.toString().equalsIgnoreCase("")) {
((CustomAdapter) AutoCompleteContactTextView.this.getAdapter()).getFilter().filter(s);
((CustomAdapter) AutoCompleteContactTextView.this.getAdapter()).notifyDataSetChanged();
ArrayList<People> arrPeople = ((CustomAdapter) AutoCompleteContactTextView.this.getAdapter()).dataList;
Log.d("We're Here", "We're here in onTextChanged");
//searchText = s;
}
if (!somethingIsSelected) {
selected = null;
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
this.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selected = (People) getAdapter().getItem(position);
GlobalVars.selectedPerson = selected;
somethingIsSelected = true;
String name = selected.getName().toString();
setText(null);
setText(selected.getName(), TextView.BufferType.SPANNABLE); //<--crash happens here.
Log.d("Something Selected", String.valueOf(somethingIsSelected));
}
});
}
I am running this on an emulator, Nexus 5 API 27. This also happens on a Pixel XL emulator running API 27. This does not crash on a real device (my Samsung Galaxy S7 Edge, running API 24).
Apparently, the value of the selected item was set to the class, instead of the string. I updated the filter for the AutoCompleteTextView and then application could get the value of the string.
this.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selected = (People) getAdapter().getItem(position);
GlobalVars.selectedPerson = selected;
somethingIsSelected = true;
Log.d("Something Selected", String.valueOf(somethingIsSelected));
}
});
@Override
public Filter getFilter() {
filter = new Filter() {
@Override
public String convertResultToString(Object resultValue) {
String str = ((People)(resultValue)).getName();
return str;
}
.....
}
The AutoCompleteTextView's get Item returns an Object, so another fix for this problem could also be changing:
@Override
public Object getItem(int position) {
return toDisplayList.get(position);
}
To
@Override
public String getItem(int position) {
return toDisplayList.get(position).getName();
}
I am using a version of this class: