在ListAdapter中实现筛选/搜索功能会返回UnsupportedOperationException。

huangapple go评论59阅读模式
英文:

Implementing Filter/Search functionality in ListAdapter returns UnsupportedOperationException

问题

我正在尝试在扩展ListAdapter的适配器类中实现搜索功能。我没有使用RecyclerAdapter,而是使用了ListAdapter。在主活动中,我使用EditTextaddTextChangedListener来实现搜索字段。我遇到了这个异常:

在ListAdapter中实现筛选/搜索功能会返回UnsupportedOperationException。

以下是我的代码:

public class NoteAdapter extends ListAdapter<Note, NoteAdapter.NoteHolder> implements Filterable {
    private List<Note> mNoteListInit;
    private OnItemClickListener mListener;

    public NoteAdapter() {
        super(DIFF_CALLBACK);
        mNoteListInit = new ArrayList<>(getCurrentList());
    } 

    @Override
    public Filter getFilter() {
        return exampleFilter;
    }

    public void setInitList(List<Note> noteList) {
        mNoteListInit = new ArrayList<>(noteList);
    }


    private Filter exampleFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            List<Note> filteredList = new ArrayList<>();

            if (constraint == null || constraint.length() == 0) {
                filteredList.addAll(mNoteListInit);
            } else {
                String filterPattern = constraint.toString().toLowerCase().trim();

                for (Note note : mNoteListInit) {
                    if (note.getTitle().toLowerCase().contains(filterPattern)) {
                        filteredList.add(note);
                    }
                }
            }
            FilterResults filterResults = new FilterResults();
            filterResults.values = filteredList;
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            submitList((List) results.values);
        }
    };
}

在MainActivity中:

mEditTextToolbarSearch.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) { }

    @Override
    public void afterTextChanged(Editable s) {
        noteAdapter.getFilter().filter(s.toString());
    }
});

mNoteViewModel.getAllNotes().observe(this, new Observer<List<Note>>() {
    @Override
    public void onChanged(List<Note> notes) {
        noteAdapter.submitList(notes);
        noteAdapter.setInitList(noteAdapter.getCurrentList());
    }
});
英文:

I am trying to implement search functionality in my Adapter class that extends ListAdapter. I am not using RecyclerAdapter but instead I am using ListAdapter. In main activity to for searching field I am using EditText and addTextChangedListener. I am having this exception:

在ListAdapter中实现筛选/搜索功能会返回UnsupportedOperationException。

This is my code:

public class NoteAdapter extends ListAdapter&lt;Note, NoteAdapter.NoteHolder&gt; implements Filterable {
private List&lt;Note&gt; mNoteListInit;
private OnItemClickListener mListener;
public NoteAdapter() {
super(DIFF_CALLBACK);
exampleListFull = new ArrayList&lt;&gt;(getCurrentList());
} 
@Override
public Filter getFilter() {
return exampleFilter;
}
public void setInitList(List&lt;Note&gt; noteList) {
mNoteListInit = new ArrayList&lt;&gt;(noteList);
}
private Filter exampleFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List&lt;Note&gt; filteredList = new ArrayList&lt;&gt;();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(mNoteListInit);
} else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (Note note : mNoteListInit) {
if (note.getTitle().toLowerCase().contains(filterPattern)) {
filteredList.add(note);
}
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
submitList((List) results.values);
}
};

In MainActivity:

mEditTextToolbarSearch.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) { }
@Override
public void afterTextChanged(Editable s) {
noteAdapter.getFilter().filter(s.toString());
}
});
mNoteViewModel.getAllNotes().observe(this, new Observer&lt;List&lt;Note&gt;&gt;() {
@Override
public void onChanged(List&lt;Note&gt; notes) {
noteAdapter.submitList(notes);
noteAdapter.setInitList(noteAdapter.getCurrentList());
}
});

答案1

得分: 1

You are getting UnsupportedOperationException Due to using .clear() on UnmodifiableCollection

Looking into your code to see where you use clear():

getCurrentList().clear();

So, definitly getCurrentList() is UnmodifiableCollection, so you can't modify it like normal Lists.

The documentation of getCurrentList() says:

The returned list may not be mutated - mutations to content must be done through submitList(List).

So, you can mutate the ListAdapter getCurrentList() through submitList

So, try to replace getCurrentList().clear() with submitList(new ArrayList())

英文:

You are getting UnsupportedOperationException Due to using .clear() on UnmodifiableCollection

Looking into your code to see where you use clear():

getCurrentList().clear();

So, definitly getCurrentList() is UnmodifiableCollection, so you can't modify it like normal Lists.

The documentation of getCurrentList() says:
> The returned list may not be mutated - mutations to content must be done through submitList(List).

So, you can mutate the ListAdapter getCurrentList() through submitList

So, try to replace getCurrentList().clear() with submitList(new ArrayList())

huangapple
  • 本文由 发表于 2020年8月2日 07:46:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/63211078.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定