DataBinding系列(三):RecyclerView中使用DataBinding

這一章,為大家?guī)?lái)利用Data Binding為RecyclerView填充數(shù)據(jù)。這里的難點(diǎn)和核心點(diǎn)就是RecyclerView中Adapter的實(shí)現(xiàn)。這里以RecyclerView多布局的情況來(lái)講解。

1、一般情況下,我們RecyclerView多布局的Adapter大致如下

public class MultiItemAdapter extends BaseBindRecyclerViewAdapter<IBaseBindingAdapterBean> {
    
    public MultiItemAdapter(Context context, List<IBaseBindingAdapterBean> mList) {
        super(context, mList);
    }

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

    @Override
    public RecyclerView.ViewHolder onCreateMyViewHolder(ViewGroup parent, int viewType) {
    }

    @Override
    public void onBindMyViewHolder(RecyclerView.ViewHolder holder, int position) {
    }

    class FruitViewHolder extends RecyclerView.ViewHolder {
    
        public FruitViewHolder(View itemView) {
            super(itemView);
        }
    }

    class TextViewHolder extends RecyclerView.ViewHolder {
      
        public TextViewHolder(View itemView) {
            super(itemView);
        }
    }

但是用了DataBinding以后,主要有3個(gè)地方發(fā)生了變化,ViewHolder, onCreateViewHolder,onBindMyViewHolder,下面就依次講解。

1.編寫(xiě)Viewholder
這里我的RecyclerView有兩種布局,并且布局全部是用databinding編寫(xiě)的,布局就先不展示了,demo里面有

class FruitViewHolder extends RecyclerView.ViewHolder {
        private ItemFruitBinding binding;

        public ItemFruitBinding getBinding() {
            return binding;
        }

        public FruitViewHolder(ItemFruitBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }

這里發(fā)生了一點(diǎn)變化,1.構(gòu)造函數(shù)的參數(shù)不再是你item布局對(duì)應(yīng)的View對(duì)象了,而是變成了你item布局對(duì)應(yīng)的ViewDataBinding對(duì)象,這個(gè)名字是和你item布局的名字相關(guān)的,我這里的item是item_fruit.xml。2.里面寫(xiě)了一個(gè)getBinding的方法,方便獲取binding對(duì)象。另一個(gè)ViewHolder也是類似的,大家也應(yīng)該發(fā)現(xiàn)了,ViewHolder里面不需要其他操作,以前的那些findViewById去獲取控件對(duì)象都不用了,因?yàn)閕tem布局里面已經(jīng)和數(shù)據(jù)綁定了。

2.重寫(xiě)onCreateViewHolder(ViewGroup parent, int viewType)
這里根據(jù)返回的viewType布局類型來(lái)創(chuàng)建不同的ViewHolder,viewType為getItemViewType(int position)方法返回的值:

@Override
    public RecyclerView.ViewHolder onCreateMyViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case R.layout.item_fruit:
                ItemFruitBinding itemFruitBinding = DataBindingUtil.inflate(inflater, R.layout.item_fruit, parent, false);
                return new FruitViewHolder(itemFruitBinding);
            case R.layout.item_text:
                ItemTextBinding itemTextBinding = DataBindingUtil.inflate(inflater, R.layout.item_text, parent, false);
                return new TextViewHolder(itemTextBinding);
            default:
                ItemFruitBinding binding = DataBindingUtil.inflate(inflater, R.layout.item_fruit, parent, false);
                return new FruitViewHolder(binding);
        }
    }

這里和以前的區(qū)別就是返回ViewHolder對(duì)象的方式不同了,是通過(guò)DataBindingUtil.inflate()的方式來(lái)獲取,因?yàn)閂iewHolder需要傳入的參數(shù)是ViewDataBinding對(duì)象。

這里還要先給大家看看,我這個(gè)viewType是怎么來(lái)的

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

mList.get(position)得到的就是當(dāng)前位置的Item對(duì)應(yīng)的JavaBean對(duì)象,而這些item對(duì)應(yīng)的Bean都去實(shí)現(xiàn)一個(gè)接口IBaseBindingAdapterItem

public interface IBaseBindingAdapterItem {
    //獲取Item的類型
    int getItemViewType();
}

然后Bean對(duì)象就會(huì)實(shí)現(xiàn)這個(gè)getItemViewType()方法,返回值就是這個(gè)Bean對(duì)應(yīng)的Item布局的layout的ID,

public class FruitItem extends BaseObservable implements IBaseBindingAdapterItem {
    private int picId; //圖片的ID
    private String describe; //描述

    public FruitItem(int picId, String describe) {
        this.picId = picId;
        this.describe = describe;
    }

    @Bindable
    public int getPicId() {
        return picId;
    }

    public void setPicId(int picId) {
        this.picId = picId;
        notifyPropertyChanged(BR.picId);
    }

    @Bindable
    public String getDescribe() {
        return describe;
    }

    public void setDescribe(String describe) {
        this.describe = describe;
        notifyPropertyChanged(BR.describe);
    }

    @Override
    public int getItemViewType() {
        return R.layout.item_fruit;
    }
}

不懂BaseObservable?那是因?yàn)檫@里我用了雙向綁定,還不懂什么是雙向綁定的童鞋,可以看我的另一篇文章。

3.onBindViewHolder(RecyclerView.ViewHolder holder,int position)方法
這是綁定數(shù)據(jù)的

@Override
    public void onBindMyViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof FruitViewHolder) {
            FruitBean fruitBean = (FruitBean) mList.get(position);
            ((FruitViewHolder) holder).getBinding().setItem(fruitBean);
            ((FruitViewHolder) holder).getBinding().executePendingBindings(); //解決databinding閃爍問(wèn)題
        } else if (holder instanceof TextViewHolder) {
            TextBean textBean = (TextBean) mList.get(position);
            ((TextViewHolder) holder).getBinding().setItem(textBean);
            ((TextViewHolder) holder).getBinding().executePendingBindings(); //解決databinding閃爍問(wèn)題
        }
    }

這里是直接通過(guò)不同item布局對(duì)應(yīng)的Binding對(duì)象去設(shè)置對(duì)應(yīng)的數(shù)據(jù),注意:executePendingBindings()不要忘記了,他用于解決databinding閃爍問(wèn)題,感興趣的可以參考 RecyclerView使用databinding出現(xiàn)數(shù)據(jù)閃爍問(wèn)題

到這里已經(jīng)實(shí)現(xiàn)了RecyclerView中使用DataBinding,估計(jì)會(huì)有人會(huì)說(shuō)你這種寫(xiě)法不夠簡(jiǎn)潔,關(guān)于這一點(diǎn),我是這么想的,如果你需要在onBindViewHolder()里面做比較復(fù)雜的操作,比如獲取到某個(gè)item的View去做一些事情,你需要知道你用的到底是哪個(gè)ViewHolder,那么用這種方式還是可以的。如果只是單純的綁定數(shù)據(jù)和顯示數(shù)據(jù),其實(shí)還有一種簡(jiǎn)單的寫(xiě)法,可以參考這篇文章,親測(cè)還是比較不錯(cuò)的。
通過(guò)Data Binding為RecyclerView打造通用Adapter

github源碼下載

歡迎學(xué)習(xí)交流這個(gè)系列的文章
DataBinding系列(一):DataBinding初認(rèn)識(shí)
DataBinding系列(二):DataBinding的基本用法
DataBinding系列(四):DataBinding進(jìn)階之路

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,366評(píng)論 25 708
  • DataBinding 庫(kù)是 Google 公司 Android Framework UI 工具團(tuán)隊(duì)開(kāi)發(fā)出來(lái)的一款...
    bravian閱讀 5,526評(píng)論 2 16
  • 睡在澡堂里的嬰兒 1 上帝在伊甸園內(nèi),創(chuàng)造了亞當(dāng)和夏娃。夏娃則出自于亞當(dāng)...
    歌齡閱讀 412評(píng)論 0 2
  • 美術(shù)生要具備的能力有哪些 01 Steve的速寫(xiě)本丟了。 身為美術(shù)專業(yè)的學(xué)生,速寫(xiě)本就像畫(huà)筆和顏料一樣...
    AKAK306920閱讀 1,018評(píng)論 1 11
  • 用小妹的話來(lái)形容回家的這一周:全身上下彌漫著濃濃的鄉(xiāng)土氣息。時(shí)光飛逝,轉(zhuǎn)眼一周就這樣結(jié)束了。 還好,留下了很多美好...
    恩煦閱讀 406評(píng)論 2 0

友情鏈接更多精彩內(nèi)容