基于 MVVM 的 RecyclerView 通用 Adapter

// MultiTypeAdapter.java
public class MultiTypeAdapter<T extends BaseItem> extends RecyclerView.Adapter<MultiTypeAdapter.ItemViewHolder> {

    private List<T> items = new ArrayList<>();


    @Override
    public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return ItemViewHolder.create(parent, viewType);
    }

    @Override
    public void onBindViewHolder(ItemViewHolder holder, int position) {
        holder.bindTo(items.get(position));
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    @Override
    public int getItemViewType(int position) {
        return items.get(position).getLayout();
    }

    public List<T> getItems() {
        return items;
    }

    public void setItem(T item) {
        clearItems();
        addItem(item);
    }

    public void setItems(List<T> items) {
        clearItems();
        addItems(items);
    }

    public void addItem(T item) {
        items.add(item);
    }

    public void addItem(T item, int index) {
        items.add(index, item);
    }

    public void addItems(List<T> items) {
        this.items.addAll(items);
    }

    public void removeItem(T item) {
        items.remove(item);
    }

    public void clearItems() {
        items.clear();
    }

    static class ItemViewHolder extends RecyclerView.ViewHolder {
        private final ViewDataBinding binding;

        static ItemViewHolder create(ViewGroup parent, int viewType) {
            ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()),
                    viewType, parent, false);
            return new ItemViewHolder(binding);
        }

        ItemViewHolder(ViewDataBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }

        void bindTo(Object item) {
            binding.setVariable(BR.item, item);
            // 立即绑定数据,否则会等到下次页面刷新绑定数据
            binding.executePendingBindings();
        }
    }
}

注 : binding.setVariable(BR.item, item); 该方法为给 xml 中预定义的变量赋值, 由于我在 xml 中给 Item 统一用了item这个变量名,所以此处使用了 BR.item, 大家可以根据实际情况进行修改

// BaseItem.java
public abstract class BaseItem extends BaseObservable implements Serializable {
    public abstract int getLayout();
}

使用方式

  1. 自定义 Item 继承 BaseItem , BaseItem 等同于 ViewHolder,但是必须要实现 getLayout() 方法,返回值为对应的布局ID.
  2. MultiTypeAdapter 初始化时需要制定 Item 类型,例如我自定义了一个 GridItem,需要在 MultiTypeAdapter 初始化时:
MultiTypeAdapter  multiTypeAdapter = new MultiTypeAdapter<GridItem>();
Last modification:November 15th, 2018 at 02:58 pm
如果觉得我的文章对你有用,请随意赞赏

Leave a Comment