RecyclerView之Adapter封裝抽取

public abstract class RecyclerAdapter<T> extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder<T>> implements
        View.OnClickListener, View.OnLongClickListener, AdapterCallback<T> {

    private final List<T> mDataList;
    private AdapterListener<T> mListener;

    /**
     * 構(gòu)造函數(shù)
     */
    public RecyclerAdapter() {
        this(null);
    }

    /**
     * 構(gòu)造函數(shù)
     */
    public RecyclerAdapter(AdapterListener<T> listener) {
        this(new ArrayList<T>(), listener);
    }

    /**
     * 構(gòu)造函數(shù)
     */
    public RecyclerAdapter(List<T> dataList, AdapterListener<T> listener) {
        this.mDataList = dataList;
        this.mListener = listener;
    }

    /**
     * 創(chuàng)建一個ViewHolder
     *
     * @param parent   RecyclerView
     * @param viewType 界面類型
     * @return ViewHolder
     */
    @Override
    public ViewHolder<T> onCreateViewHolder(ViewGroup parent, int viewType) {
        // 將xml (id為viewType)的文件初始化為一個root View
        View root = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
        // 通過子類必須實現(xiàn)的方法,得到一個ViewHolder
        ViewHolder<T> holder = onCreateViewHolder(root, viewType);
        // 設(shè)置View的Tag為ViewHolder堵泽,進行雙向綁定  通過tag獲取ViewHolder
        root.setTag(R.id.tag_recycler_holder, holder);
        // 設(shè)置view的點擊事件
        root.setOnClickListener(this);
        root.setOnLongClickListener(this);
        // 進行界面注解綁定
        holder.unbinder = ButterKnife.bind(holder, root);
        // 綁定callback
        holder.callback = this;
        return holder;
    }

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

    protected abstract int getItemViewType(int position, T data);

    protected abstract ViewHolder<T> onCreateViewHolder(View view, int viewType);

    /**
     * 綁定數(shù)據(jù)到一個ViewHolder上
     *
     * @param holder   ViewHolder
     * @param position 坐標(biāo)
     */
    @Override
    public void onBindViewHolder(ViewHolder<T> holder, int position) {
        // 得到需要綁定的數(shù)據(jù)
        T data = mDataList.get(position);
        // 綁定數(shù)據(jù)
        holder.bind(data);
    }


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

    /**
     * 插入一條數(shù)據(jù)并通知插入
     *
     * @param data
     */
    public void add(T data) {
        mDataList.add(data);
//        notifyDataSetChanged();
        notifyItemInserted(mDataList.size() - 1);
    }

    /**
     * 插入一堆數(shù)據(jù)腌逢,并通知這段集合更新
     *
     * @param dataList
     */
    public void addAll(T... dataList) {
        if (dataList != null && dataList.length > 0) {
            int startPos = mDataList.size();
            Collections.addAll(mDataList, dataList);
            notifyItemRangeInserted(startPos, dataList.length);
        }
    }

    /**
     * 插入一堆數(shù)據(jù)宾尚,并通知這段集合更新
     *
     * @param dataList
     */
    public void addAll(Collection<T> dataList) {
        if (dataList != null && dataList.size() > 0) {
            int startPos = mDataList.size();
            mDataList.addAll(dataList);
            notifyItemRangeInserted(startPos, dataList.size());
        }
    }

    /**
     * 刪除操作
     */
    public void clean() {
        mDataList.clear();
        notifyDataSetChanged();
    }

    /**
     * 替換一個新的集合蕉陋。其中包括了清空
     *
     * @param dataList 一個新的集合
     */
    public void replace(Collection<T> dataList) {
        mDataList.clear();
        if (dataList == null || dataList.size() == 0)
            return;
        mDataList.addAll(dataList);
        notifyDataSetChanged();
    }

    @Override
    public void upData(T data, ViewHolder<T> viewHolder) {
        int pos = viewHolder.getAdapterPosition();
        if (pos > 0) {
            mDataList.remove(pos);
            mDataList.add(pos, data);
            notifyItemChanged(pos);
        }
    }

    @Override
    public void onClick(View v) {
        ViewHolder viewHolder = (ViewHolder) v.getTag(R.id.tag_recycler_holder);
        if (this.mListener != null) {
            // 得到ViewHolder當(dāng)前對應(yīng)的適配器中的坐標(biāo)
            int pos = viewHolder.getAdapterPosition();
            // 回調(diào)方法
            this.mListener.onItemClick(viewHolder, mDataList.get(pos));
        }
    }

    @Override
    public boolean onLongClick(View v) {
        ViewHolder viewHolder = (ViewHolder) v.getTag(R.id.tag_recycler_holder);
        if (this.mListener != null) {
            // 得到ViewHolder當(dāng)前對應(yīng)的適配器中的坐標(biāo)
            int pos = viewHolder.getAdapterPosition();
            // 回調(diào)方法
            this.mListener.onItemLongClick(viewHolder, mDataList.get(pos));
        }
        return false;
    }

    /**
     * 設(shè)置適配器監(jiān)聽
     *
     * @param adapterListener
     */
    public void setListerner(AdapterListener<T> adapterListener) {
        this.mListener = adapterListener;
    }

    /**
     * 自定義點擊監(jiān)聽器
     *
     * @param <T>
     */
    public interface AdapterListener<T> {
        //  當(dāng)Cell點擊時觸發(fā)
        void onItemClick(RecyclerAdapter.ViewHolder holder, T data);

        //  當(dāng)Cell長按時觸發(fā)
        void onItemLongClick(RecyclerAdapter.ViewHolder holder, T data);
    }
    
    public static abstract class ViewHolder<T> extends RecyclerView.ViewHolder {

        protected T mData;
        private Unbinder unbinder;
        private AdapterCallback<T> callback;

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

        /**
         * 用于綁定數(shù)據(jù)的觸發(fā)
         *
         * @param data 綁定的數(shù)據(jù)
         */
        void bind(T data) {
            this.mData = data;
            onBind(mData);
        }

        /**
         * 當(dāng)觸發(fā)綁定數(shù)據(jù)的時候的回調(diào)竖螃,必須復(fù)寫
         *
         * @param data 綁定的數(shù)據(jù)
         */
        protected abstract void onBind(T data);

        /**
         * Holder自己對自己對應(yīng)的Data進行更新操作
         *
         * @param data
         */
        public void updataData(T data) {
            if (this.callback != null) {
                this.callback.upData(data, this);
            }
        }
    }
    
    public static abstract class AdapterListenerImpl<T> implements AdapterListener<T>{

        @Override
        public void onItemClick(ViewHolder holder, T data) {
            
        }

        @Override
        public void onItemLongClick(ViewHolder holder, T data) {

        }
    } 
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闭专,一起剝皮案震驚了整個濱河市奴潘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌影钉,老刑警劉巖画髓,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異平委,居然都是意外死亡奈虾,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門肆汹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來愚墓,“玉大人,你說我怎么就攤上這事昂勉±瞬幔” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵岗照,是天一觀的道長村象。 經(jīng)常有香客問我,道長攒至,這世上最難降的妖魔是什么厚者? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮迫吐,結(jié)果婚禮上库菲,老公的妹妹穿的比我還像新娘。我一直安慰自己志膀,他們只是感情好熙宇,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著溉浙,像睡著了一般烫止。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上戳稽,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天馆蠕,我揣著相機與錄音,去河邊找鬼。 笑死互躬,一個胖子當(dāng)著我的面吹牛播赁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吨铸,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼行拢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了诞吱?” 一聲冷哼從身側(cè)響起舟奠,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎房维,沒想到半個月后沼瘫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡咙俩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年耿戚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阿趁。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡膜蛔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出脖阵,到底是詐尸還是另有隱情皂股,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布命黔,位于F島的核電站呜呐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏悍募。R本人自食惡果不足惜蘑辑,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坠宴。 院中可真熱鬧洋魂,春花似錦、人聲如沸喜鼓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颠通。三九已至,卻和暖如春膀懈,著一層夾襖步出監(jiān)牢的瞬間顿锰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留硼控,地道東北人刘陶。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像牢撼,于是被迫代替她去往敵國和親匙隔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容