Recyclerview onBindViewHolder вызывается раньше фильтрации данных
У моего адаптера RecyclerView есть фильтр, который фильтрует список в соответствии с настройками из преференсов. Проблема в том, что при инициализации списка уже могут быть установлены настройки фильтра, так как в конструктор адаптера я передаю изначально полный список, я так понимаю, что onBindViewHolder вызывается раньше, чем произойдет фильтр списка, в следствие чего у меня возникает IndexOutOfBoundsException, так как OnBindViewHolder начинает выполняться с полным списком, но в процессе выполнения данные изменяются. Код адаптера
public class EventsAdapter extends RecyclerView.Adapter<EventsAdapter.EventHolder> implements Filterable {
private List<OptimaEvent> mEvents;
private Context mContext;
private List<OptimaEvent> mFilteredEvents;
private EventFilter mFilter;
public EventsAdapter(List<OptimaEvent> events, Context context) {
mEvents = events;
mFilteredEvents = mEvents;
mContext = context;
}
@NonNull
@Override
public EventsAdapter.EventHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
EventItemBinding binding = DataBindingUtil.inflate(inflater, R.layout.event_item, parent, false);
return new EventsAdapter.EventHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull EventHolder holder, int position) {
OptimaEvent event = mFilteredEvents.get(position);
holder.bind(event);
}
@Override
public int getItemCount() {
return mFilteredEvents.size();
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new EventFilter();
}
return mFilter;
}
private class EventFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<OptimaEvent> filterList = new ArrayList<>();
for (OptimaEvent event : mEvents) {
if (AppPreferences.isWarningFilter(mContext)){
if (event.getAlertLevel() == 1) {
filterList.add(event);
}
}
if (AppPreferences.isInfoFilter(mContext)) {
if (event.getAlertLevel() == 0) {
filterList.add(event);
}
}
if (event.getAlertLevel() == 2) {
filterList.add(event);
}
}
mFilteredEvents = filterList;
FilterResults results = new FilterResults();
results.values = mFilteredEvents;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mFilteredEvents = (ArrayList<OptimaEvent>) results.values;
notifyDataSetChanged();
}
}
class EventHolder extends RecyclerView.ViewHolder {
private EventItemBinding mBinding;
EventHolder(@NonNull EventItemBinding binding) {
super(binding.getRoot());
mBinding = binding;
}
void bind(OptimaEvent event) {
mBinding.setEvent(event);
mBinding.eventItem.setOnClickListener((View view) -> {
});
mBinding.executePendingBindings();
}
}
}
Фрагмент инициализации RecyclerView.
@Override
public void initView(List<OptimaEvent> events) {
Log.i(TAG, "initView: ");
mAdapter = new EventsAdapter(events, getContext());
LinearLayoutManager layoutManager = new
LinearLayoutManager(getActivity());
layoutManager.setStackFromEnd(true);
filterAdapter();
mBinding.recyclerView.setLayoutManager(layoutManager);
mBinding.recyclerView.setAdapter(mAdapter);
mBinding.swipeRefresh.setRefreshing(false);
}
Ответы (1 шт):
Применяйте фильтр к копии списка, и после этот новый список (копию) уже передавайте в адаптер. Не меняйте непосредственно сам список в адаптере, работайте только с его копией.