Android RecyclerView添加頭部和底部實(shí)例詳解
Android RecyclerView添加頭部和底部實(shí)例詳解
如果只是想添加頭部,可是使用GitHub里面這個(gè)項(xiàng)目,它可以為LinearLayoutManager,GridLayoutManager ,StaggeredGridLayoutManager布局的RecyclerView添加header。使用起來也十分簡單;
只需將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)用。
目前該庫適用于LinearLayoutManager,StaggeredGridLayoutManager和GridLayoutManager布局的RecyclerViews。只支持垂直布局LayoutManager。如果你打算在RecyclerView中使用setOnScrollListener(…)方法,確保在setOnScrollListener(…)的attachTo(…)方法之前使用。
當(dāng)然我們也可以自己寫一個(gè)添加頭部和底部的RecyclerView。它實(shí)現(xiàn)的基本原理也是通過getItemViewType方法返回不同的類型來添加頭部和底部。
首先我們自定義一個(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沒有實(shí)現(xiàn),下面我們就來看下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
// 的差值來比較,是調(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
// 的差值來比較,是調(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è)接口,來調(diào)用RecyclerWrapAdapter對(duì)象:
public interface WrapperAdapter {
public RecyclerView.Adapter getWrappedAdapter() ;
}
這樣我們就可以把RecyclerView布局改成WrapRecyclerView就可以了,然后調(diào)用addHeaderView或者addFooterView就可以添加頭部和尾部了。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Android實(shí)現(xiàn)仿淘寶購物車增加和減少商品數(shù)量功能demo示例
這篇文章主要介紹了Android實(shí)現(xiàn)仿淘寶購物車增加和減少商品數(shù)量功能,結(jié)合實(shí)例形式分析了Android實(shí)現(xiàn)的淘寶購物車商品數(shù)量變換與計(jì)算相關(guān)技巧,需要的朋友可以參考下2016-07-07
Android自定義view實(shí)現(xiàn)進(jìn)度條指示效果
這篇文章主要為大家詳細(xì)介紹了Android自定義view實(shí)現(xiàn)進(jìn)度條指示效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
appium運(yùn)行各種坑爹報(bào)錯(cuò)問題及解決方法【推薦】
這篇文章主要介紹了 appium運(yùn)行各種坑爹報(bào)錯(cuò)問題及解決方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06
Android設(shè)計(jì)模式之適配器(Adapter)模式
這篇文章主要介紹了Android設(shè)計(jì)模式之適配器(Adapter)模式,以源碼解析的方式分析適配器模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android通過Handler與AsyncTask兩種方式動(dòng)態(tài)更新ListView(附源碼)
這篇文章主要介紹了Android通過Handler與AsyncTask兩種方式動(dòng)態(tài)更新ListView的方法,結(jié)合實(shí)例形式分析了ListView動(dòng)態(tài)更新的常用技巧,并附上完整實(shí)例源碼供讀者下載,需要的朋友可以參考下2015-12-12
Android網(wǎng)格布局GridView學(xué)習(xí)使用
這篇文章主要為大家詳細(xì)介紹了Android網(wǎng)格布局GirdView的學(xué)習(xí)使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Android超清晰6.0權(quán)限申請(qǐng)AndPermission
這篇文章主要介紹了Android超清晰6.0權(quán)限申請(qǐng)AndPermission,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
Android ExpandableListView展開列表控件使用實(shí)例
這篇文章主要介紹了Android ExpandableListView展開列表控件使用實(shí)例,本文實(shí)現(xiàn)了一個(gè)類似手機(jī)QQ好友列表的界面效果,需要的朋友可以參考下2014-07-07

