為RecyclerView添加header和footer

為recyclerView添加header和footer也是我們在開發(fā)過程中經(jīng)常遇見的,實(shí)現(xiàn)起來也是比較簡單的廷粒。下面介紹怎么添加header和footer

其實(shí)我們可以將header和footer看做是特殊的item泪幌,在添加他之后肴焊,我們值需要對(duì)他進(jìn)行一些特殊的處理就可以達(dá)到我們想到的效果其屏。

為了簡單起見,我們直接在adapter中進(jìn)行這一部分的操作措译。

在adapter中新建一些標(biāo)識(shí)的int值别凤,用于區(qū)分是否需要添加header和footer,如下所示:

public static final int TYPE_HEADER = 0;  //說明是帶有Header的
public static final int TYPE_FOOTER = 1;  //說明是帶有Footer的
public static final int TYPE_NORMAL = 2;  //說明是不帶有header和footer的

對(duì)外暴露添加header和footer方法领虹,參考如下:

private View mHeaderView;
private View mFooterView;

public void setHeaderView(View headerView) {
        mHeaderView = headerView;
        notifyItemInserted(0);
    }

    public void setFooterView(View footerView) {
        mFooterView = footerView;
        notifyItemInserted(getItemCount() - 1);
    }

覆寫getItemViewType()方法规哪,用于區(qū)分是否需要添加head和footer

 @Override
    public int getItemViewType(int position) {
        if (mHeaderView == null && mFooterView == null) {
            return TYPE_NORMAL;
        }
        if (position == 0) {
            return TYPE_HEADER;
        }
        if (position == getItemCount() - 1) {
            return TYPE_FOOTER;
        }
        return TYPE_NORMAL;
    }

在onCreateViewHolder中添加對(duì)header和footer的支持

if (mHeaderView != null && viewType == TYPE_HEADER) {
    return new ItemHolder(mHeaderView);
}
if (mFooterView != null && viewType == TYPE_FOOTER) {
    return new ItemHolder(mFooterView);
}

在onBindViewHolder增加對(duì)header和footer的處理,如果當(dāng)前對(duì)象是header或者footer直接返回即可塌衰。
如果有header的話诉稍,因?yàn)閔eader也需要占一個(gè)位子,所以顯示的時(shí)候需要顯示當(dāng)前位子的前一個(gè)位子最疆。

if (getItemViewType(position) == TYPE_HEADER) return;
else if (getItemViewType(position) == TYPE_FOOTER) return;
else {
    if (holder instanceof MyAdapterWith.ItemHolder) {
        position = holder.getLayoutPosition();
        position = mHeaderView == null ? position : position - 1;
        //計(jì)算當(dāng)前的位置杯巨,如果添加了header的話,header也需要占用一個(gè)位置
        if (position < datas.size()) {
            holder.imageView.setImageResource(datas.get(position).getId());
            holder.teTitle.setText(datas.get(position).getTitle());
            holder.teContent.setText(datas.get(position).getContent());
        }
    }
}

然后努酸,需要在ViewHolder中添加對(duì)header和footer的支持

  public class ItemHolder extends RecyclerView.ViewHolder {
        public ImageView imageView;
        public TextView teTitle;
        public TextView teContent;


        public ItemHolder(View itemView) {
            super(itemView);
            if (itemView == mHeaderView)
                return;
            if (itemView == mFooterView)
                return;

            imageView = (ImageView) itemView.findViewById(R.id.item_image);
            teTitle = (TextView) itemView.findViewById(R.id.item_title);
            teContent = (TextView) itemView.findViewById(R.id.item_content);
        }

最后服爷,我們就可以直接在activity中進(jìn)行添加了

View view  = LayoutInflater.from(this).inflate(R.layout.head,mRecyclerView,false);
mMyAdapter.setHeaderView(view);
View footer = LayoutInflater.from(this).inflate(R.layout.foot,mRecyclerView,false);
mMyAdapter.setFooterView(footer);

其中R.layout.headR.layout.foot是head和foot的布局。

當(dāng)然获诈。這樣寫好之后仍源,我們可以觀察到這樣的結(jié)果:


添加header
添加header

添加foot
添加foot

基本正常,但是當(dāng)我們使用GridLayoutManager時(shí)舔涎,會(huì)發(fā)現(xiàn)這樣的問題笼踩。


添加foot
添加foot

可以看到,這里我們的header和footer被當(dāng)作一個(gè)item终抽,并沒有實(shí)現(xiàn)我們想到的置頂占行的效果戳表。
解決方案:
利用GridLayoutManager的setSpanSizeLookup方法:
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        if (getItemViewType(position) == TYPE_HEADER || getItemViewType(position) == TYPE_FOOTER)
            return gridLayoutManager.getSpanCount();
        else
            return 1;
    }
});

這里的getSpanSize()方法返回的值決定了每個(gè)position上item占據(jù)的單元格個(gè)數(shù)。為了簡單起見昼伴,可以將這個(gè)方法放在adapter中匾旭。代碼如下:

 @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if(manager==null)       Log.d("TAG", "manager=null");

        if (manager instanceof GridLayoutManager) {

            final GridLayoutManager gridLayoutManager = (GridLayoutManager) manager;
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    if (getItemViewType(position) == TYPE_HEADER || getItemViewType(position) == TYPE_FOOTER)
                        return gridLayoutManager.getSpanCount();
                    else
                        return 1;
                }
            });
        }
    }

最后,再為StaggeredGridLayoutManager做一些處理圃郊。

 @Override
    public void onViewAttachedToWindow(ItemHolder holder) {
        super.onViewAttachedToWindow(holder);
        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        if (lp != null
                && lp instanceof StaggeredGridLayoutManager.LayoutParams) {
            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
            if (mHeaderView != null)
                p.setFullSpan(holder.getLayoutPosition() == 0);
//            if(mFooterView!=null)
//                 p.setFullSpan(holder.getLayoutPosition() ==datas.size());
        }
    }

到此价涝,添加header和footer的基本操作就完成了。不過在日常使用中持舆,我們肯定會(huì)對(duì)每一次都需要編寫一個(gè)這么復(fù)雜的header類感覺很麻煩色瘩,這里可以考慮封裝一下。
對(duì)了逸寓,在使用的過程中居兆,如果需要適配GridLayoutManager的話,在activity的recycler的setAdapter方法之前竹伸,需要先調(diào)用 mRecyclerView.setLayoutManager(mManager);
參見代碼:

RecyclerView.LayoutManager mManager = new new GridLayoutManager(this,2);
mRecyclerView.setLayoutManager(mManager);

 mRecyclerView.setAdapter(mMyAdapter);

如果這樣寫:

RecyclerView.LayoutManager mManager = new new GridLayoutManager(this,2);
 mRecyclerView.setAdapter(mMyAdapter);
 mRecyclerView.setLayoutManager(mManager);

那么泥栖,我們在adapter中編寫的對(duì)GridLayoutManager的適配就無法獲取到recycler而無法起作用簇宽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吧享,隨后出現(xiàn)的幾起案子魏割,更是在濱河造成了極大的恐慌,老刑警劉巖钢颂,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钞它,死亡現(xiàn)場離奇詭異,居然都是意外死亡殊鞭,警方通過查閱死者的電腦和手機(jī)遭垛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來操灿,“玉大人耻卡,你說我怎么就攤上這事∩撸” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵幌蚊,是天一觀的道長谤碳。 經(jīng)常有香客問我,道長溢豆,這世上最難降的妖魔是什么蜒简? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮漩仙,結(jié)果婚禮上搓茬,老公的妹妹穿的比我還像新娘。我一直安慰自己队他,他們只是感情好卷仑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著麸折,像睡著了一般锡凝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上垢啼,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天窜锯,我揣著相機(jī)與錄音,去河邊找鬼芭析。 笑死锚扎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的馁启。 我是一名探鬼主播驾孔,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了助币?” 一聲冷哼從身側(cè)響起浪听,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎眉菱,沒想到半個(gè)月后迹栓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俭缓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年克伊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片华坦。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡愿吹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出惜姐,到底是詐尸還是另有隱情犁跪,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布歹袁,位于F島的核電站坷衍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏条舔。R本人自食惡果不足惜枫耳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望孟抗。 院中可真熱鬧迁杨,春花似錦、人聲如沸凄硼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽帆喇。三九已至警医,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坯钦,已是汗流浹背预皇。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留婉刀,地道東北人吟温。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像突颊,于是被迫代替她去往敵國和親鲁豪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子潘悼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

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