5

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));

        }
    });
}

Happens when I select a contact.

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).

Kristy Welsh
  • 7,828
  • 12
  • 64
  • 106
  • Updated my code. This happens in the init() of the autocompletetextview. – Kristy Welsh May 18 '18 at 20:22
  • Do you crash if you remove `setText(null)`? Do you crash if you use `setText(name)` instead of `setText(selected.getName(), TextView.BufferType.SPANNABLE);`? Do you crash if you use `setText(selected.getName());` instead of `setText(selected.getName(), TextView.BufferType.SPANNABLE);`? In what environments does this crash? (OS version, particular devices versus an emulator) This is a disturbing error; I'm trying to get a sense of the scope and possible workarounds. – CommonsWare May 18 '18 at 20:23
  • @CommonsWare - I've tried all those combinations. I do not crash if I do setText(null). I do crash in all other cases. – Kristy Welsh May 18 '18 at 20:24
  • @CommonsWare I am running an emulator of Nexus 5 API 27. It does not crash on my Samsung Galaxy S7 Edge. – Kristy Welsh May 18 '18 at 20:25
  • "I do not crash if I do setText(null). I do crash in all other cases." -- I am confused, then, as your code shows `setText(null)`, yet you say that it crashes on the following line. Try putting your "real" `setText()` call (not the `null` one) in a `Runnable` and `post()` that, instead of doing the `setText()` directly in `onItemClick()`. – CommonsWare May 18 '18 at 20:36
  • @CommonsWare same error. – Kristy Welsh May 18 '18 at 20:43
  • What's the value of selected.getName() when the app crashes? – Rishabh Jain May 22 '18 at 19:23
  • @RishabhJain It's set equal to the String value of the name of the contact. – Kristy Welsh May 22 '18 at 19:58

1 Answers1

3

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:

https://github.com/lolobosse/ContactsAutoCompleteTextView/blob/master/contactsautocompletetextview/src/main/java/com/meyerlaurent/cactv/AutoCompleteContactTextView.java

Kristy Welsh
  • 7,828
  • 12
  • 64
  • 106