RecycleView在DataBinding上的通用Adapter

DataBinding是google新推出的MVVM框架的實現,類似於前端的AngularJs,可在Xml文件中直接綁定數據源,也可直接通過對應的類名直接獲得界面的控件,使用後可拋棄註解框架的使用;RecycleView是ListView,GridView等的結合體,通過進行對RecycleView進行一系列的設置,實現對應的效果,感覺以後可以逐漸取代ListView等控件,在這裏簡單介紹一下,具體的介紹與使用以後補充。下面是在兩者的基礎上實現的一個通用的Adapter,可直接實例化setAdapter。
1。BaseViewHolder

import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * ViewHolder基類(相當於一個界面類,內部存放DataBing類對象,用於之後與數據進行綁定)
 * itemView相當於之前的ContentView
 * Created by yzy on 2016/9/26.
 */
public class BaseViewHolder<T extends ViewDataBinding> extends RecyclerView.ViewHolder{
    private T dataBing;

    public BaseViewHolder(View itemView) {
        super(itemView);
    }

    public T getDataBing() {
        return dataBing;
    }

    public void setDataBing(T dataBing) {
        this.dataBing = dataBing;
    }
}

2。BaseRecycleViewAdapter

import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;


/**
 * RecycleViewAdapter基類(可直接初始化)
 * Created by yzy on 2016/9/26.
 */
public class BaseRecycleViewAdapter<T,K extends ViewDataBinding> extends RecyclerView.Adapter<BaseViewHolder<K>> {

    protected List<T> lists;    //數據源
    protected int resouceId;    //佈局ID
    protected int variableId;   //佈局內VariableId

    public BaseRecycleViewAdapter(List<T> lists, int resouceId,int variableId) {
        this.lists = lists;
        this.resouceId = resouceId;
        this.variableId = variableId;
    }

    /**
     * 創建綁定數據的ViewHolder(實際上就相當於初始化出來界面)
     * @param parent
     * @param viewType
     * @return
     */
    @Override
    public BaseViewHolder<K> onCreateViewHolder(ViewGroup parent, int viewType){
        K itemBing = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()),resouceId,parent,false);   //獲取DataBing相當於獲取View
        BaseViewHolder<K> holder = new BaseViewHolder<K>(itemBing.getRoot());//初始化ViewHolder存放View
        holder.setDataBing(itemBing);
        return holder;
    }

    @Override
    public void onBindViewHolder(final BaseViewHolder<K> holder, final int position){
        T data = lists.get(position);//獲取數據
        holder.getDataBing().setVariable(variableId,data);//賦值
        if(listener!=null) {//設置單擊事件
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    listener.onItemClick(holder.getDataBing(),position);
                }
            });
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    listener.onLongItemClick(holder.getDataBing(),position);
                    return false;
                }
            });
        }
        holder.getDataBing().executePendingBindings();//刷新界面
    }

    @Override
    public int getItemCount() {
        return lists == null?0:lists.size();
    }

    /**
     * TODO: 對RecyclerView的數據更新,必須remove掉Item以及DataItem,這樣纔會觸發item改變的動畫,如果直接調用notifyDataSetChanged則不會觸發動畫的效果
     */
    /**
     * 插入Item,並且更新界面
     * @param t
     * @param position
     */
    public void addItem(T t , int position){
        if(lists == null){
            lists = new ArrayList<>();
        }
        if(position == -1){
            position = lists.size();
        }
        lists.add(position,t);
        notifyItemInserted(position);
    }

    public void addItem(T t){
        addItem(t,-1);
    }

    /**
     * 添加Items
     * @param ts
     * @param position
     */
    public void addItems(List<T> ts,int position){
        if(lists == null){
            lists = new ArrayList<>();
        }
        if(position == -1){
            position = lists.size();
        }
        lists.addAll(position,ts);
        notifyItemInserted(position);
    }

    public void addItems(List<T> ts){
        addItems(ts,-1);
    }

    /**
     * remove Item
     * @param t
     */
    public void removeItem(T t){
        if(lists == null){
            notifyDataSetChanged();
            return ;
        }
        int position = lists.indexOf(t);
        if(position != -1) {
            lists.remove(t);
            notifyItemRemoved(position);
        }
    }

    public void removeItem(int position){
        if(lists == null){
            notifyDataSetChanged();
            return ;
        }
        if(position>=0 && position<lists.size()) {
            lists.remove(position);
            notifyItemRemoved(position);
        }
    }



    //自定義item單擊事件
    protected OnItemClickListener listener;

    public void setListener(OnItemClickListener listener) {
        this.listener = listener;
    }

    public interface OnItemClickListener{
        public void onItemClick(ViewDataBinding dataBinding, int position);
        public void onLongItemClick(ViewDataBinding dataBinding,int position);
    }

3。調用

 bing.layoutMenu.funRecyclerviewSetting.setAdapter(new BaseRecycleViewAdapter<Map<String,Object>,FunRecyclerviewItemBinding>(settingData,R.layout.fun_recyclerview_item,BR.dataMap));

總結:代碼比較簡單,就不一一解釋了。就是在使用DataBinding過程中發現,不會自動生成BR文件,每次都是直接手動引入BR文件,以及其中的variableId也會報錯,卻能編譯跑起來,但是總會提示找不到BR類,知道的可以告訴我一聲,謝謝!!!

發佈了32 篇原創文章 · 獲贊 7 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章