Ответ 1
Вот как я настраиваю типы многозадачности для RecyclewView.
Сначала я покажу код, а затем поясню ниже.
@SuppressWarnings("unchecked")
public class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {
private final List<Wrapper<?>> items;
public BaseAdapter() {
this.items = new ArrayList<>();
}
@Override
public int getItemViewType(int position) {
return items.get(position).viewType;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return ViewType.values()[viewType].onCreateViewHolder(parent);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.onBind(items.get(position));
}
@Override
public int getItemCount() {
return items.size();
}
public void simulateAddItems() {
items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
items.add(new Wrapper<>(ViewType.BOTTOM.viewTYpe(), new BottomData()));
notifyDataSetChanged();
}
public enum ViewType {
USER {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
return new UserViewHolder(itemView);
}
},
BOTTOM {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
return new BottomViewHolder(itemView);
}
};
public abstract ViewHolder onCreateViewHolder(ViewGroup parent);
public int viewTYpe() {
return ordinal();
}
}
static class Wrapper<T> {
final int viewType;
final T data;
public Wrapper(int viewType, T data) {
this.viewType = viewType;
this.data = data;
}
}
public static class ViewHolder<T> extends RecyclerView.ViewHolder {
private T item;
public ViewHolder(View itemView) {
super(itemView);
}
public void onBind(T item) {
}
}
public static class UserViewHolder extends ViewHolder<User> {
public UserViewHolder(View itemView) {
super(itemView);
}
@Override
public void onBind(User item) {
super.onBind(item);
}
}
public static class BottomViewHolder extends ViewHolder<BottomData> {
public BottomViewHolder(View itemView) {
super(itemView);
}
@Override
public void onBind(BottomData item) {
super.onBind(item);
}
}
static class User {
// user fields & method
}
static class BottomData {
// bottom data fields & method
}
}
Вы можете видеть, что адаптер имеет что-то особенное:
-
Данные адаптера являются обобщенными и простираются от класса
Wrapper
. КлассWrapper
просто POJO-класс содержит два поляviewType
иitem
данных.viewType
будет проходить черезgetItemViewType(int position)
, аitem
- данные для каждого держателя вида. -
Общий
ViewHolder
сT
является видом данных для владельца вида. Вы можете увидеть два пользовательских держателя видаUserViewHolder
иBottomViewHolder
, начиная сViewHolder
с этими данными. (Таким образом, вonBind
каждого держателя вида будут указаны точные данные, которые они хотят использовать, → нет необходимости бросать. Потому что мы уже в литье). -
В перечислении
viewType
содержится весь вид типа адаптера. Кроме того, в виде вида у нас есть методViewHolder onCreateViewHolder(ViewGroup parent)
, поэтому мы можем проще сделать viewHolder изviewType
. Я думаю, что для наших глаз легче видеть Холдера относительно ViewType.
Кроме того, у нас есть метод viewType()
, который просто возвращает ordinal()
перечисления.
В качестве ссылки в java docs
этот метод не может использоваться. Но в этом случае я считаю, что это достаточно справедливо для использования (потому что оно уникально).
Итак, в методе onCreateViewHolder
адаптера мы можем просто позвонить:
return ViewType.values()[viewType].onCreateViewHolder(parent);
и в onBindViewHolder
будем называть holder.onBind(items.get(position));
.
Наконец, я сделал simulateAddItems
для демонстрации того, как мы добавляем элемент в адаптер.
Вот некоторые впечатления при работе с настраиваемым типом вида для RecycleView. Надеюсь, это полезно и поможет другим людям.