Skip to content

Instantly share code, notes, and snippets.

@technoir42
Last active November 14, 2017 19:40
Show Gist options
  • Save technoir42/63b7993d16eee273e61a8a54a03e8344 to your computer and use it in GitHub Desktop.
Save technoir42/63b7993d16eee273e61a8a54a03e8344 to your computer and use it in GitHub Desktop.
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public abstract class BinderRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final SparseArray<Binder<?, ?>> binders = new SparseArray<>();
protected List<Item<?>> items = Collections.emptyList();
@Override
public final RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final Binder<?, ?> binder = binders.get(viewType);
return binder.createViewHolder(LayoutInflater.from(parent.getContext()), parent, viewType);
}
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public final void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Item<?> item = items.get(position);
final Binder binder = binders.get(item.getType());
binder.bindViewHolder(holder, item.getPayload());
}
@Override
public final int getItemCount() {
return items.size();
}
@Override
public final long getItemId(int position) {
return items.get(position).getId();
}
@Override
public final int getItemViewType(int position) {
return items.get(position).getType();
}
@SuppressWarnings("unchecked")
public final <T> T getItemPayload(int position) {
return (T) items.get(position).getPayload();
}
protected final void registerBinder(int type, Binder<?, ?> binder) {
if (binders.get(type) != null) {
throw new IllegalStateException("Binder for type " + type + " is already registered");
}
binders.append(type, Objects.requireNonNull(binder));
}
public interface Binder<T, VH extends RecyclerView.ViewHolder> {
VH createViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType);
void bindViewHolder(VH holder, T value);
}
public static final class StaticViewBinder implements Binder<Void, StaticViewBinder.ViewHolder> {
private final int layoutId;
public StaticViewBinder(@LayoutRes int layoutId) {
this.layoutId = layoutId;
}
@Override
public ViewHolder createViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType) {
final View view = inflater.inflate(layoutId, parent, false);
return new ViewHolder(view);
}
@Override
public void bindViewHolder(ViewHolder holder, Void unused) {
}
static class ViewHolder extends RecyclerView.ViewHolder {
ViewHolder(View itemView) {
super(itemView);
}
}
}
protected static final class Item<T> {
private final long id;
private final int type;
private final T payload;
public static <T> Item<T> create(int type, T payload) {
return new Item<>(RecyclerView.NO_ID, type, payload);
}
public static <T> Item<T> create(long id, int type, T payload) {
return new Item<>(id, type, payload);
}
private Item(long id, int type, T payload) {
this.id = id;
this.type = type;
this.payload = payload;
}
public long getId() {
return id;
}
public int getType() {
return type;
}
public T getPayload() {
return payload;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final Item<?> other = (Item<?>) o;
return id == other.id &&
type == other.type &&
Objects.equals(payload, other.payload);
}
@Override
public int hashCode() {
return Objects.hash(id, type, payload);
}
@Override
public String toString() {
return "Item{" +
"id=" + (id == RecyclerView.NO_ID ? "NO_ID" : Long.toString(id)) +
", type=" + type +
", payload=" + payload +
'}';
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment