RecyclerView:實現(xiàn)帶header的grid

轉(zhuǎn)自:http://www.open-open.com/lib/view/open1437662138631.html

原文:RecyclerView: Grid with header

GridView和ListView有許多的相似之處女淑,不過也有一個顯著的不同:沒有header和footer∠疲現(xiàn)在它們兩者都可以用RecyclerView實現(xiàn)皆刺,我想看看如何在grid上添加header鹿鳖。

GridLayoutManager

我用GridLayoutManager創(chuàng)建了一個spanCount為2的RecylcerView。

注:spanCount即列數(shù)勺良。這里GridLayoutManager的第二個參數(shù)就是spanCount草巡。

RecyclerView?recyclerView?=?(RecyclerView)?findViewById(

R.id.recycler_view);

recyclerView.addItemDecoration(new?MarginDecoration(this));

recyclerView.setHasFixedSize(true);

recyclerView.setLayoutManager(new?GridLayoutManager(this,?2));

recyclerView.setAdapter(new?NumberedAdapter(30));

NumberedAdapter以字符串的形式顯示了每個item的position憎夷,在點擊的時候顯示一個toast。

GridLayoutActivity.java

可變的span size

在上面的基本設(shè)置中躬柬,我們的spanCount為2拜轨,每個item的span size為1,因此一個header需要的span size則為2楔脯。在我嘗試著添加header之前撩轰,我想先看看如何設(shè)置?span size。其實很簡單昧廷。

注:span size表示一個item的跨度堪嫂,跨度了多少個span。

GridLayoutManager?manager?=?new?GridLayoutManager(this,?3);

manager.setSpanSizeLookup(new?GridLayoutManager.SpanSizeLookup()?{

@Override

public?int?getSpanSize(int?position)?{

return?(3?-?position?%?3);

}

});

recyclerView.setLayoutManager(manager);

setSpanSizeLookup可以讓你根據(jù)position來設(shè)置?span size木柬,上面代碼中的公式所得到的?span size依次是3, 2, 1, 3, 2, 1...

GridLayoutVariableSpanSizeActivity.java

頭部(header)

現(xiàn)在讓我們來添加一個header皆串!我們需要一個提供兩種view類型的adapter,一個為header一個為普通的item眉枕《窀矗可以看看HeaderNumberedAdapter,它在構(gòu)造函數(shù)中把一個view作為header速挑,然后把它存在一個成員變量中谤牡。

package?com.sqisland.android.recyclerview;

import?android.support.v7.widget.RecyclerView;

import?android.view.LayoutInflater;

import?android.view.View;

import?android.view.ViewGroup;

import?android.widget.Toast;

import?java.util.ArrayList;

import?java.util.List;

public?class?HeaderNumberedAdapter?extends?RecyclerView.Adapter?{

private?static?final?int?ITEM_VIEW_TYPE_HEADER?=?0;

private?static?final?int?ITEM_VIEW_TYPE_ITEM?=?1;

private?final?View?header;

private?final?List?labels;

public?HeaderNumberedAdapter(View?header,?int?count)?{

if?(header?==?null)?{

throw?new?IllegalArgumentException("header?may?not?be?null");

}

this.header?=?header;

this.labels?=?new?ArrayList(count);

for?(int?i?=?0;?i?<?count;?++i)?{

labels.add(String.valueOf(i));

}

}

public?boolean?isHeader(int?position)?{

return?position?==?0;

}

@Override

public?TextViewHolder?onCreateViewHolder(ViewGroup?parent,?int?viewType)?{

if?(viewType?==?ITEM_VIEW_TYPE_HEADER)?{

return?new?TextViewHolder(header);

}

View?view?=?LayoutInflater.from(parent.getContext()).inflate(R.layout.item,?parent,?false);

return?new?TextViewHolder(view);

}

@Override

public?void?onBindViewHolder(final?TextViewHolder?holder,?final?int?position)?{

if?(isHeader(position))?{

return;

}

final?String?label?=?labels.get(position?-?1);??//?Subtract?1?for?header

holder.textView.setText(label);

holder.textView.setOnClickListener(new?View.OnClickListener()?{

@Override

public?void?onClick(View?v)?{

Toast.makeText(

holder.textView.getContext(),?label,?Toast.LENGTH_SHORT).show();

}

});

}

@Override

public?int?getItemViewType(int?position)?{

return?isHeader(position)???ITEM_VIEW_TYPE_HEADER?:?ITEM_VIEW_TYPE_ITEM;

}

@Override

public?int?getItemCount()?{

return?labels.size()?+?1;

}

}

其中TextViewHolder的代碼為:

package?com.sqisland.android.recyclerview;

import?android.support.v7.widget.RecyclerView;

import?android.view.View;

import?android.widget.TextView;

public?class?TextViewHolder?extends?RecyclerView.ViewHolder?{

public?TextView?textView;

public?TextViewHolder(View?itemView)?{

super(itemView);

textView?=?(TextView)?itemView.findViewById(R.id.text);

}

}

在RecyclerView新建一個view的時候,如果處于header的位置姥宝,我們用view holder來封裝這個header翅萤。onBindViewHolder中不必對header做任何事情,因為它的邏輯是在activity中處理的腊满。

回到activity套么。我們需要用一個header來初始化HeaderNumberedAdapter,同時重寫setSpanSizeLookup碳蛋,讓header橫跨所有列胚泌。

final?GridLayoutManager?manager?=?new?GridLayoutManager(this,?2);

recyclerView.setLayoutManager(manager);

View?header?=?LayoutInflater.from(this).inflate(

R.layout.header,?recyclerView,?false);

header.setOnClickListener(new?View.OnClickListener()?{

@Override

public?void?onClick(View?v)?{

Toast.makeText(v.getContext(),?R.string.grid_layout_header,

Toast.LENGTH_SHORT).show();

}

});

final?HeaderNumberedAdapter?adapter

=?new?HeaderNumberedAdapter(header,?30);

recyclerView.setAdapter(adapter);

manager.setSpanSizeLookup(new?GridLayoutManager.SpanSizeLookup()?{

@Override

public?int?getSpanSize(int?position)?{

return?adapter.isHeader(position)???manager.getSpanCount()?:?1;

}

});

我們inflate header,定義它的點擊事件肃弟,使用它去構(gòu)造adapter玷室。然后再setSpanSizeLookup中零蓉,我們在header所處的位置返回和span count (列數(shù))相等的?span size。

總結(jié)

為了用RecyclerView創(chuàng)建一個帶header的grid:

定義一個具有兩種view類型的adapter阵苇,一個為header一個為普通item壁公。

nflate一個header,把它傳遞給adapter绅项。

重寫GridLayoutManager中的setSpanSizeLookup紊册,在header所處的位置返回和span count (列數(shù))相等的?span size。

源碼:https://github.com/chiuki/android-recyclerview

ps:在我的g+上有人評論說如果你不需要RecyclerView的功能快耿,比如animation囊陡,reordering,staggering等掀亥,你也可以從AOSP中拷貝HeaderGridView.java撞反。

來自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0722/3214.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搪花,隨后出現(xiàn)的幾起案子遏片,更是在濱河造成了極大的恐慌,老刑警劉巖撮竿,帶你破解...
    沈念sama閱讀 212,185評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吮便,死亡現(xiàn)場離奇詭異,居然都是意外死亡幢踏,警方通過查閱死者的電腦和手機(jī)髓需,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,445評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來房蝉,“玉大人僚匆,你說我怎么就攤上這事〈罨茫” “怎么了咧擂?”我有些...
    開封第一講書人閱讀 157,684評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長檀蹋。 經(jīng)常有香客問我松申,道長,這世上最難降的妖魔是什么续扔? 我笑而不...
    開封第一講書人閱讀 56,564評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮焕数,結(jié)果婚禮上纱昧,老公的妹妹穿的比我還像新娘。我一直安慰自己堡赔,他們只是感情好识脆,可當(dāng)我...
    茶點故事閱讀 65,681評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般灼捂。 火紅的嫁衣襯著肌膚如雪离例。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,874評論 1 290
  • 那天悉稠,我揣著相機(jī)與錄音宫蛆,去河邊找鬼。 笑死的猛,一個胖子當(dāng)著我的面吹牛耀盗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播卦尊,決...
    沈念sama閱讀 39,025評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼叛拷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了岂却?” 一聲冷哼從身側(cè)響起忿薇,我...
    開封第一講書人閱讀 37,761評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎躏哩,沒想到半個月后署浩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,217評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡震庭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,545評論 2 327
  • 正文 我和宋清朗相戀三年瑰抵,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片器联。...
    茶點故事閱讀 38,694評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡二汛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拨拓,到底是詐尸還是另有隱情肴颊,我是刑警寧澤,帶...
    沈念sama閱讀 34,351評論 4 332
  • 正文 年R本政府宣布渣磷,位于F島的核電站婿着,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏醋界。R本人自食惡果不足惜竟宋,卻給世界環(huán)境...
    茶點故事閱讀 39,988評論 3 315
  • 文/蒙蒙 一铁蹈、第九天 我趴在偏房一處隱蔽的房頂上張望系奉。 院中可真熱鬧,春花似錦攒磨、人聲如沸逐样。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,778評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挪捕,卻和暖如春粗梭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背级零。 一陣腳步聲響...
    開封第一講書人閱讀 32,007評論 1 266
  • 我被黑心中介騙來泰國打工断医, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人妄讯。 一個月前我還...
    沈念sama閱讀 46,427評論 2 360
  • 正文 我出身青樓孩锡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親亥贸。 傳聞我的和親對象是個殘疾皇子躬窜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,580評論 2 349

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