Как сделать адаптер для SQLite для RecyclerView?
Нашел готовое решение, и очень интересно его краткое объяснение, т.к. не до конца его понимаю. Почему мой код работает с тормозами а тот что в решении не должен. Дело в том где я расположен код переноса элементов в массив? Или именно из-за переноса он и работает медленно? Метод onBindViewHolder вызывается при появлении на экране нового представления, т.е. код оттуда выполняется постепенно: вначале появляется представление, выполняется код, затем следующее и тд?
Самый волнующий вопрос как исправить именно мой код, чтобы он работал нормально?
public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.ViewHolder> {
private Listener mListener;
private Cursor mCursor;
interface Listener {
void onClick(int position);
}
public void setListener(Listener mListener){
this.mListener = mListener;
}
public TaskAdapter (Cursor cursor){
mCursor = cursor;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private CardView mCardView;
public ViewHolder(CardView v){
super(v);
mCardView = v;
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
CardView cardView = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.card_task, parent, false);
return new ViewHolder(cardView);
}
@Override
public void onBindViewHolder(ViewHolder holder,final int position) {
if (mCursor != null){
ArrayList<String> titles = new ArrayList<String>();
ArrayList<String> descriptions = new ArrayList<String>();
ArrayList<Integer> imageIds = new ArrayList<Integer>();
mCursor.moveToFirst();
while (!mCursor.isAfterLast()){
titles.add(mCursor.getString(0));
descriptions.add(mCursor.getString(1));
imageIds.add(mCursor.getInt(2));
mCursor.moveToNext();
}
CardView cardView = holder.mCardView;
ImageView imageView = cardView.findViewById(R.id.task_image);
Drawable drawable = ContextCompat.getDrawable(cardView.getContext(), imageIds.get(position));
imageView.setImageDrawable(drawable);
TextView titleView = cardView.findViewById(R.id.task_title);
titleView.setText(titles.get(position));
TextView descriptionView = cardView.findViewById(R.id.task_description);
descriptionView.setText(descriptions.get(position));
cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mListener != null) {
mListener.onClick(position);
}
}
});
}
}
@Override
public int getItemCount(){
return mCursor.getCount();
}
}
Ответы (1 шт):
Ваш адаптер не должен знать нечего о всяких SQLite и любых других подобных вещах.
По хорошему адаптер должен уметь только рисовать список который вы ему дали. Он не должен ходить в базу, в сеть или куда бы то ни было ещё. Это не его ответственность.
У вас должна быть сущность типа Presenter/ViewModel которая загрузит и подготовит данные для адаптера. И сделать она это должна не на UI потоке. Когда она это сделает она должна передать в адаптер уже готовый список данных.
В противном случае у вас будут лаги в интерфейсе, потому что адаптер будет делать запросы в БД на UI потоке.