Android RecyclerView添加頭部和底部的方法
如果只是想添加頭部,可是使用GitHub里面這個(gè)項(xiàng)目,它可以為L(zhǎng)inearLayoutManager,GridLayoutManager ,StaggeredGridLayoutManager布局的RecyclerView添加header。使用起來(lái)也十分簡(jiǎn)單;
只需將RecyclerViewHeader布局放在RecyclerView的上層。
<FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal|top" /> <com.bartoszlipinski.recyclerviewheader.RecyclerViewHeader android:id="@+id/header" android:layout_width="match_parent" android:layout_height="100dp" android:layout_gravity="center_horizontal|top"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="header"/> </com.bartoszlipinski.recyclerviewheader.RecyclerViewHeader> </FrameLayout>
然后獲得RecyclerViewHeader對(duì)象:
RecyclerViewHeader header = (RecyclerViewHeader) findViewById(R.id.header);
把RecyclerViewHeader賦予RecyclerView
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); // set LayoutManager for your RecyclerView header.attachTo(recyclerView, true);
注意事項(xiàng)
RecyclerViewHeader必須在RecyclerView設(shè)置了LayoutManager之后調(diào)用。
目前該庫(kù)適用于LinearLayoutManager,StaggeredGridLayoutManager和GridLayoutManager布局的RecyclerViews。只支持垂直布局LayoutManager。如果你打算在RecyclerView中使用setOnScrollListener(…)方法,確保在setOnScrollListener(…)的attachTo(…)方法之前使用。
當(dāng)然我們也可以自己寫(xiě)一個(gè)添加頭部和底部的RecyclerView。它實(shí)現(xiàn)的基本原理也是通過(guò)getItemViewType方法返回不同的類型來(lái)添加頭部和底部。
首先我們自定義一個(gè)RecyclerView:
public class WrapRecyclerView extends RecyclerView {
public ArrayList<View> mHeaderViews = new ArrayList<>();
public ArrayList<View> mFooterViews = new ArrayList<>();
//添加Adapter
public Adapter mAdapter;
public WrapRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public WrapRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WrapRecyclerView(Context context) {
super(context);
}
public void addHeaderView(View view){
mHeaderViews.clear();
mHeaderViews.add(view);
if(mAdapter!=null){
if(!(mAdapter instanceof RecyclerWrapAdapter)){
mAdapter = new RecyclerWrapAdapter(mHeaderViews,mFooterViews,mAdapter);
}
}
}
public void addFooterView(View view){
mFooterViews.clear();
mFooterViews.add(view);
if(mAdapter!=null){
if(!(mAdapter instanceof RecyclerWrapAdapter)){
mAdapter = new RecyclerWrapAdapter(mHeaderViews,mFooterViews,mAdapter);
}
}
}
public void setAdapter(Adapter adapter){
if (mHeaderViews.isEmpty()&&mFooterViews.isEmpty()){
super.setAdapter(adapter);
}else {
adapter = new RecyclerWrapAdapter(mHeaderViews,mFooterViews,adapter) ;
super.setAdapter(adapter);
}
mAdapter = adapter ;
}
}
我們會(huì)看到我們有一個(gè)RecyclerWrapAdapter沒(méi)有實(shí)現(xiàn),下面我們就來(lái)看下RecyclerWrapAdapter,這個(gè)也是實(shí)現(xiàn)添加頭部和尾部的關(guān)鍵。
public class RecyclerWrapAdapter extends RecyclerView.Adapter implements WrapperAdapter{
private RecyclerView.Adapter mAdapter;
private ArrayList<View> mHeaderViews;
private ArrayList<View> mFootViews;
static final ArrayList<View> EMPTY_INFO_LIST =
new ArrayList<View>();
private int mCurrentPosition;
public RecyclerWrapAdapter(ArrayList<View> mHeaderViews, ArrayList<View> mFootViews, RecyclerView.Adapter mAdapter){
this.mAdapter = mAdapter;
if (mHeaderViews == null) {
this.mHeaderViews = EMPTY_INFO_LIST;
} else {
this.mHeaderViews = mHeaderViews;
}
if (mFootViews == null) {
this.mFootViews = EMPTY_INFO_LIST;
} else {
this.mFootViews = mFootViews;
}
}
public int getHeadersCount() {
return mHeaderViews.size();
}
public int getFootersCount() {
return mFootViews.size();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == RecyclerView.INVALID_TYPE) {
return new HeaderViewHolder(mHeaderViews.get(0));
} else if (viewType == RecyclerView.INVALID_TYPE - 1) {
return new HeaderViewHolder(mFootViews.get(0));
}
return mAdapter.onCreateViewHolder(parent, viewType);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
//如果頭部不為空,那么我們就要先添加頭部,所以我們只要
//把前面幾個(gè)position給頭部,當(dāng)position小于頭部總數(shù)的時(shí)候,
//我們返回頭部view。再判斷原Adapter 的 count 與當(dāng)前 position
// 的差值來(lái)比較,是調(diào)用原 Adapter 的 getView 方法,還是獲取 footView
// 的 view。
int numHeaders = getHeadersCount();
if (position < numHeaders) {
return;
}
int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mAdapter != null) {
adapterCount = mAdapter.getItemCount();
if (adjPosition < adapterCount) {
mAdapter.onBindViewHolder(holder, adjPosition);
return;
}
}
}
@Override
public int getItemCount() {
if (mAdapter != null) {
return getHeadersCount() + getFootersCount() + mAdapter.getItemCount();
} else {
return getHeadersCount() + getFootersCount();
}
}
@Override
public RecyclerView.Adapter getWrappedAdapter() {
return mAdapter;
}
@Override
public int getItemViewType(int position) {
//增加兩個(gè)類型
//RecyclerView.INVALID_TYPE 添加頭部
//RecyclerView.INVALID_TYPE-1 添加尾部
//如果頭部不為空,那么我們就要先添加頭部,所以我們只要
//把前面幾個(gè)position給頭部,當(dāng)position小于頭部總數(shù)的時(shí)候,
//我們返回頭部類型。再判斷原Adapter 的 count 與當(dāng)前 position
// 的差值來(lái)比較,是調(diào)用原 Adapter 的 類型,還是獲取 footView
// 的類型。
mCurrentPosition = position ;
int numHeaders = getHeadersCount();
if(position<numHeaders){
return RecyclerView.INVALID_TYPE ;
}
int adjPosition = position - numHeaders ;
int adapterCount = 0 ;
if(mAdapter!=null){
adapterCount = mAdapter.getItemCount() ;
if(adjPosition < adapterCount){
return mAdapter.getItemViewType(adjPosition);
}
}
return RecyclerView.INVALID_TYPE - 1;
}
private static class HeaderViewHolder extends RecyclerView.ViewHolder {
public HeaderViewHolder(View itemView) {
super(itemView);
}
}
}
我們還可以實(shí)現(xiàn)一個(gè)接口,來(lái)調(diào)用RecyclerWrapAdapter對(duì)象:
public interface WrapperAdapter {
public RecyclerView.Adapter getWrappedAdapter() ;
}
這樣我們就可以把RecyclerView布局改成WrapRecyclerView就可以了,然后調(diào)用addHeaderView或者addFooterView就可以添加頭部和尾部了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家學(xué)習(xí)Android 軟件編程有所幫助。
相關(guān)文章
手把手教學(xué)Android用jsoup解析html實(shí)例
本篇文章主要介紹了手把手教學(xué)Android用jsoup解析html實(shí)例,jsoup 是一款Java 的HTML解析器。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
Android應(yīng)用開(kāi)發(fā)的版本更新檢測(cè)升級(jí)功能實(shí)現(xiàn)示例
本文對(duì)Android版本更新的知識(shí)做全面的總結(jié),主要包括開(kāi)發(fā)中版本的設(shè)置,如何檢測(cè)本程序的版本,版本的更新判斷和顯示,新版本程序的安裝2022-04-04
Android消息通知Notification常用方法(發(fā)送消息和接收消息)
最近在做消息通知類Notification的相關(guān)業(yè)務(wù),利用閑暇時(shí)間總結(jié)一下,主要分為兩部分來(lái)記錄:發(fā)送消息和接收消息,對(duì)Android消息通知相關(guān)知識(shí)感興趣的朋友一起看看吧2024-02-02
Android動(dòng)畫(huà)之3D翻轉(zhuǎn)效果實(shí)現(xiàn)函數(shù)分析
Android中的翻轉(zhuǎn)動(dòng)畫(huà)效果的實(shí)現(xiàn),Android中并沒(méi)有提供直接做3D翻轉(zhuǎn)的動(dòng)畫(huà),所以關(guān)于3D翻轉(zhuǎn)的動(dòng)畫(huà)效果需要我們自己實(shí)現(xiàn),那么我們首先來(lái)分析一下Animation 和 Transformation,感興趣的朋友可以了解下啊2013-01-01
Android如何通過(guò)手機(jī)自動(dòng)獲取短信驗(yàn)證碼
注冊(cè)帳號(hào)時(shí),經(jīng)常需要手機(jī)獲取驗(yàn)證碼,Android如何通過(guò)手機(jī)自動(dòng)獲取短信驗(yàn)證碼,下面看看小編給大家分享的一段代碼,感興趣的小伙伴們可以參考一下2016-03-03
Android Studio導(dǎo)入第三方類庫(kù)的方法
這篇文章主要介紹了Android Studio導(dǎo)入第三方類庫(kù)的方法,導(dǎo)入*.jar包、導(dǎo)入第三方j(luò)ava類庫(kù)含源碼包以及aar的引入,需要的朋友可以參考下2016-07-07

