在使用AutoCompleteTextView进行选择时崩溃

5

显然,这个这个是我遇到的同样问题,不过我的TextView是一个AutoCompleteTextView。我从我的联系人列表中进行选择时,每次做出选择时都会出现以下错误:

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)

似乎是由于光标被选择在允许范围之外导致的。上面链接中提供的解决方法似乎没有帮助。这就是崩溃发生的地方:

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

        }
    });
}

选择联系人时出现的情况。

我正在模拟器上运行此应用程序,使用的是 Nexus 5 API 27。在运行 API 27 的 Pixel XL 模拟器上也会出现这种情况。但在真实设备上(我的三星 Galaxy S7 Edge,运行 API 24)不会崩溃。


更新了我的代码。这是在autocompletetextview的init()函数中发生的。 - Kristy Welsh
如果您删除 setText(null),会导致崩溃吗?如果您使用 setText(name) 而不是 setText(selected.getName(), TextView.BufferType.SPANNABLE);,会导致崩溃吗?如果您使用 setText(selected.getName()); 而不是 setText(selected.getName(), TextView.BufferType.SPANNABLE);,会导致崩溃吗?在哪些环境下会出现这种崩溃?(操作系统版本、特定设备与模拟器之间的区别)这是一个令人不安的错误;我正在尝试了解其范围和可能的解决方法。 - CommonsWare
@CommonsWare 我正在运行 Nexus 5 API 27 的模拟器。它在我的三星 Galaxy S7 Edge 上没有崩溃。 - Kristy Welsh
如果我使用setText(null),我不会崩溃。但在其他情况下,我会崩溃。因此,我很困惑,你的代码中显示了setText(null),但你说它会在下一行崩溃。尝试将“真正”的setText()调用(而不是null)放入一个Runnable中,并在onItemClick()中直接post()它,而不是直接执行setText()。 - CommonsWare
@CommonsWare 同样的错误。 - Kristy Welsh
显示剩余3条评论
1个回答

3

显然,所选项的值被设置为类而不是字符串。我更新了AutoCompleteTextView的过滤器,应用程序就可以获取字符串的值了。

    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;
            }
        .....
     }   

AutoCompleteTextView的getItem方法返回一个对象,因此解决这个问题的另一种方法也可以是更改:
    @Override
    public Object getItem(int position) {
        return toDisplayList.get(position);
    }

    @Override
    public String getItem(int position) {
        return toDisplayList.get(position).getName();
    }

我正在使用这个类的一个版本:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接