AndroidUI初探②RecyclerView.Adapter簡單封裝

前言

早期文章 荡含, 如今搬運(yùn)過來 释液, RecyclerView用法相信都會误债,這里主要介紹一下簡單的封裝寝蹈。

不管我們是在使用早期的ListView還是使用強(qiáng)大的RecyclerView ,我們都需要去實(shí)現(xiàn)其控件的Adapter 箫老,將數(shù)據(jù)與控件綁定起來 耍鬓。不管是ListViewAdapter還是RecyclerViewAdapter 牲蜀,都需要我們實(shí)現(xiàn)大量的方法 ,重復(fù)的去編寫相同的操作 涣达,為了減少不必要的編碼 度苔,就需要將Adapter的共性抽取出來 寇窑,做成一個(gè)通用的Adapter ,以后需要實(shí)現(xiàn)Adapter 完残,只需要繼承我們自己寫的Adapter就OK了 横漏。

分析

不管是我們的ListViewAdapter還是RecyclerViewAdapter 缎浇,其主要有兩點(diǎn) :
第一、 外界提供給我們的數(shù)據(jù)源 二蓝, 這個(gè)是變化的 刊愚。
第二踩验、 外界提供給我們的布局文件資源(也可拓展為布局View) 箕憾, 這個(gè)也是變化,需要傳遞的參數(shù)
另 : RecyclerView需要我們自己實(shí)現(xiàn)Item的各種事件
如果布局中需要Context 钠龙,也可以作為參數(shù)傳入 碴里,創(chuàng)建多個(gè)構(gòu)造函數(shù)

編寫 :

要封裝RecyclerView.Adapter畅买,就需要搞清楚,RecyclerViewAdapter主要實(shí)現(xiàn)三個(gè)方法 帝火,onCreateViewHolderonBindViewHolder蠢壹、getItemCount 九巡,還有一個(gè)ViewHolder類 。我們來分析分析 疏日, 這幾個(gè)方法和類 撒汉。

onCreateViewHolder

主要構(gòu)件RecyclerView每個(gè)Item布局對象 睬辐,與ViewHolder關(guān)聯(lián) 溯饵,達(dá)到復(fù)用視圖的效果,并傳遞給 onBindViewHolder 隘谣,因?yàn)槲覀兊牟季謱ο蠖际荲iew 洪橘, 所以這個(gè)地方 棵帽, 我們可以根據(jù)傳遞進(jìn)來的資源文件infalter成一個(gè)View 逗概,亦或是傳進(jìn)來的View逾苫,再與ViewHolder關(guān)聯(lián) 铅搓, 此處我們就可以對外屏蔽掉了 搀捷。


    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View view = LayoutInflater.from(parent.getContext()).inflate(mItemLayoutRes, parent,
                false);
        ViewHolder viewHolder = new ViewHolder(view);

        // 初始化Item事件監(jiān)聽
        initOnItemListener(viewHolder);

        return viewHolder;
    }

onBindViewHolder

主要講數(shù)據(jù)與ViewHolder里面的控件相關(guān)聯(lián) ,因?yàn)槲乙獙?shí)現(xiàn)不同RecyclerView Item的數(shù)據(jù)顯示 怀偷,所以這個(gè)地方不能寫死 椎工,需要我們根據(jù)情況 蜀踏,將數(shù)據(jù)綁定到不同的控件上面 , 這里需要抽象方法傳遞出來數(shù)據(jù) 颅痊, 讓繼承我們的Adapter做操作


    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
    {
        Object o = mItems.get(position);
        convertView((ViewHolder) holder,o);
    }

getItemCount


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

返回我們的Item總條數(shù)

ViewHolder

將ViewHolder類抽取出來八千,主要是為了更加方便的進(jìn)行View組件的操作恋捆,這個(gè)類 重绷,主要是為我們的控件復(fù)用服務(wù) ,因?yàn)樵贏dapter每個(gè)Item與ViewHolder關(guān)聯(lián) 愤钾,所以在此類中 能颁, 我們可以做一些獲取控件的簡便操作 。

    
        private View mConvertView;
        private SparseArray<View> mViews;
    
        public ViewHolder(View itemView)
        {
            super(itemView);
            mViews = new SparseArray<>() ;
            mConvertView = itemView ;
        }
    
        /**
         * 根據(jù)資源獲取View對象
         * @param res
         * @param <T>
         * @return
         */
        public <T extends View> T getView(@IdRes int res) {
    
            View view = mViews.get(res);
            if (view == null) {
                view = mConvertView.findViewById(res) ;
                mViews.put(res,view);
            }
            return (T) view;
        }


完整Adapter代碼


    /**
     * Created by Zeno on 2016/6/8.
     *
     *  簡介 :
     *      抽象類的抽取 ,主要是抽取一些有共性的方法和參數(shù) 敌土。
     *
     *  分析:
     *      不管是ListView還是RecyclerView 兴枯,主要有兩個(gè)點(diǎn)需要實(shí)現(xiàn):
     *          第一 :外界提供的數(shù)據(jù)源
     *          第二 :外界提供的布局
     *      這兩個(gè)點(diǎn)是明確從外部傳入的 财剖,所以首先這兩個(gè)點(diǎn)不能固定 悠夯,需要作為參數(shù)從外部傳入
     *      如果有一些資源需要用到上下文 ,還需要傳入Context
     *
     *
     */
    public abstract class SimpleBaseRecyclerAdapter extends RecyclerView.Adapter
    {
        // each item layout res
        private int mItemLayoutRes;
        // total item data set
        private List<?> mItems;
    
        private ItemClickListener mItemClickListener ;
        private ItemLongClickListnener mItemLongClickListnener ;
    
        public SimpleBaseRecyclerAdapter(@LayoutRes int mItemLayoutRes, List<?> items)
        {
            this.mItemLayoutRes = mItemLayoutRes;
            // 如果沒有傳入的數(shù)據(jù) 峰伙,則自動創(chuàng)建一個(gè)空的集合 疗疟,防止報(bào)空指針
            this.mItems = items ==null ? new ArrayList<>() : items;
        }
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
        {
            View view = LayoutInflater.from(parent.getContext()).inflate(mItemLayoutRes, parent,
                    false);
            ViewHolder viewHolder = new ViewHolder(view);
    
            // 初始化Item事件監(jiān)聽
            initOnItemListener(viewHolder);
    
            return viewHolder;
        }
    
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
            Object o = mItems.get(position);
            convertView((ViewHolder) holder,o);
        }
    
        @Override
        public int getItemCount()
        {
            return mItems.size();
        }
    
        public abstract void convertView(ViewHolder viewHolder, Object itemObj) ;
    
    
        /**
         * init set item view listener
         * @param holder
         */
        private void initOnItemListener(final RecyclerView.ViewHolder holder) {
                if (mItemClickListener != null) {
                    holder.itemView.setOnClickListener(new View.OnClickListener()
                    {
                        @Override
                        public void onClick(View v)
                        {
                            Object o = mItems.get(holder.getLayoutPosition());
                            mItemClickListener.onItemClick(v,o ,holder.getLayoutPosition());
                        }
                    });
                }
    
                if (mItemLongClickListnener != null) {
                    holder.itemView.setOnLongClickListener(new View.OnLongClickListener()
                    {
                        @Override
                        public boolean onLongClick(View v)
                        {
                            Object o = mItems.get(holder.getLayoutPosition());
                            mItemLongClickListnener.onItemLongClick(v,o,holder.getLayoutPosition());
                            return true;
                        }
                    });
                }
        }
    
        /**
         * set item view click
         * @param listener
         */
        public void setOnItemClickListener(ItemClickListener listener) {
            mItemClickListener = listener ;
        }
    
        /**
         * set item view long click
         * @param listener
         */
        public void setOnItemLongClickListener(ItemLongClickListnener listener) {
            mItemLongClickListnener = listener ;
        }
    
    
        public interface ItemClickListener {
            void onItemClick(View view ,Object itemObj , int position) ;
        }
    
        public interface ItemLongClickListnener {
            void onItemLongClick(View view ,Object itemObj, int position) ;
        }
    }



完整ViewHolder代碼


    /**
     * Created by Zeno on 2016/6/8.
     *
     * ViewHolder主要是做一些與控件布局有關(guān)的操作 ,所有我們可以在這邊簡化一下獲取控件對象的代碼
     */
    public class ViewHolder extends RecyclerView.ViewHolder
    {
        private View mConvertView;
        private SparseArray<View> mViews;
    
        public ViewHolder(View itemView)
        {
            super(itemView);
            mViews = new SparseArray<>() ;
            mConvertView = itemView ;
        }
    
        /**
         * 根據(jù)資源獲取View對象
         * @param res
         * @param <T>
         * @return
         */
        public <T extends View> T getView(@IdRes int res) {
    
            View view = mViews.get(res);
            if (view == null) {
                view = mConvertView.findViewById(res) ;
                mViews.put(res,view);
            }
            return (T) view;
        }
    
        /**
         * 提供TextView和Button設(shè)置文本簡化操作
         * @param idRes
         * @param charSequence
         * @return
         */
        public ViewHolder setText(@IdRes int idRes , CharSequence charSequence) {
            View view = getView(idRes);
            if (view instanceof TextView) {
                ((TextView)view).setText(charSequence);
            }else if (view instanceof Button) {
                ((Button)view).setText(charSequence);
            }
    
            return this ;
        }
    
        /**
         * 提供TextView和Button設(shè)置文本顏色簡化操作
         * @param idRes
         * @param color
         * @return
         */
        public ViewHolder setTextColor(@IdRes int idRes , int color) {
            View view = getView(idRes);
            if (view instanceof TextView) {
                ((TextView)view).setTextColor(color);
            }else if (view instanceof Button) {
                ((Button)view).setTextColor(color);
            }
            return this ;
        }
    
    
        /**
         * 設(shè)置指定ViewId的背景顏色
         * @param idRes
         * @param color
         * @return
         */
        public ViewHolder setBackgroundColor(@IdRes int idRes , int color) {
    
            View view = getView(idRes);
            view.setBackgroundColor(color);
    
            return this;
        }
    
        /**
         * 設(shè)置ImageView顯示圖片
         * @param idRes
         * @param res
         * @return
         */
        public ViewHolder setImageResoruce(@IdRes int idRes , @DrawableRes int res) {
            View view = getView(idRes);
            if (view instanceof ImageView) {
                ((ImageView)view).setImageResource(res);
            }
    
            return this ;
        }
    
        /**
         * 設(shè)置指定控件ID的點(diǎn)擊事件
         * @param idRes
         * @param listener
         * @return
         */
        public ViewHolder setOnClickListener(@IdRes int idRes , View.OnClickListener listener) {
    
            View view = getView(idRes);
            view.setOnClickListener(listener);
    
            return this;
        }
    
        /**
         * 設(shè)置指定控件ID的長按事件
         * @param idRes
         * @param listener
         * @return
         */
        public ViewHolder setOnLongClickListener(@IdRes int idRes , View.OnLongClickListener listener) {
            View view = getView(idRes);
            view.setOnLongClickListener(listener);
    
            return this;
        }
    
        /**
         * 設(shè)置指定控件的TAG
         * @param idRes
         * @param tag
         * @return
         */
        public ViewHolder setTag(@IdRes int idRes , Object tag) {
            View view = getView(idRes);
            view.setTag(tag);
    
            return this;
        }
    
        /**
         * 獲取指定控件的TAG
         * @param idRes
         * @return
         */
        public Object getTag(@IdRes int idRes) {
            View view = getView(idRes);
            return  view.getTag() ;
        }
    
    }


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瞳氓,一起剝皮案震驚了整個(gè)濱河市策彤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌匣摘,老刑警劉巖音榜,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瞬场,居然都是意外死亡贯被,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門汽煮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人翎卓,你說我怎么就攤上這事坯门。” “怎么了现恼?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵刽酱,是天一觀的道長润文。 經(jīng)常有香客問我,道長赠法,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮眶熬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘贸弥。我一直安慰自己哲鸳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著脸秽,像睡著了一般薇正。 火紅的嫁衣襯著肌膚如雪雕沿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼吊圾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛板丽,可吹牛的內(nèi)容都是我干的酥泞。 我是一名探鬼主播似炎,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼悯许,長吁一口氣:“原來是場噩夢啊……” “哼瘩扼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起栽燕,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后猛计,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盗温,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡批销,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片是趴。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拜秧,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布淹辞,位于F島的核電站爷速,受9級特大地震影響廉沮,放射性物質(zhì)發(fā)生泄漏滤灯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一渤滞、第九天 我趴在偏房一處隱蔽的房頂上張望录肯。 院中可真熱鬧,春花似錦、人聲如沸眉抬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春恤筛,著一層夾襖步出監(jiān)牢的瞬間煎殷,已是汗流浹背珠移。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓漾唉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,303評論 25 707
  • 一令杈、概述 對于RecyclerView的學(xué)習(xí)给赞,主要是需要掌握以下幾點(diǎn): 數(shù)據(jù):Adapter 使用:Recycle...
    澤毛閱讀 7,306評論 1 23
  • 特別聲明: 本文轉(zhuǎn)發(fā)自:【江清清的博客】http://blog.csdn.net/developer_jiangq...
    _猜火車_閱讀 37,461評論 11 70
  • Tangram是阿里出品盆耽、用于快速實(shí)現(xiàn)組合布局的框架模型析恢,在手機(jī)天貓Android&iOS版 內(nèi)廣泛使用 該框架提...
    wintersweett閱讀 3,306評論 0 1
  • 看了今天的晨讀,發(fā)現(xiàn)自己的焦慮就是遵循著一套過時(shí)的“規(guī)則”。從小到大參加過很多比賽蒸苇,參加演奏比賽前總會擔(dān)心...
    圓舞amour閱讀 287評論 3 4