Android RecyclerView添加頭部和底部的方法
如果只是想添加頭部,可是使用GitHub里面這個項目,它可以為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對象:
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);
注意事項
RecyclerViewHeader必須在RecyclerView設(shè)置了LayoutManager之后調(diào)用。
目前該庫適用于LinearLayoutManager,StaggeredGridLayoutManager和GridLayoutManager布局的RecyclerViews。只支持垂直布局LayoutManager。如果你打算在RecyclerView中使用setOnScrollListener(…)方法,確保在setOnScrollListener(…)的attachTo(…)方法之前使用。
當(dāng)然我們也可以自己寫一個添加頭部和底部的RecyclerView。它實現(xiàn)的基本原理也是通過getItemViewType方法返回不同的類型來添加頭部和底部。
首先我們自定義一個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 ; } }
我們會看到我們有一個RecyclerWrapAdapter沒有實現(xiàn),下面我們就來看下RecyclerWrapAdapter,這個也是實現(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) { //如果頭部不為空,那么我們就要先添加頭部,所以我們只要 //把前面幾個position給頭部,當(dāng)position小于頭部總數(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) { //增加兩個類型 //RecyclerView.INVALID_TYPE 添加頭部 //RecyclerView.INVALID_TYPE-1 添加尾部 //如果頭部不為空,那么我們就要先添加頭部,所以我們只要 //把前面幾個position給頭部,當(dāng)position小于頭部總數(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); } } }
我們還可以實現(xiàn)一個接口,來調(diào)用RecyclerWrapAdapter對象:
public interface WrapperAdapter { public RecyclerView.Adapter getWrappedAdapter() ; }
這樣我們就可以把RecyclerView布局改成WrapRecyclerView就可以了,然后調(diào)用addHeaderView或者addFooterView就可以添加頭部和尾部了。
以上就是本文的全部內(nèi)容,希望對大家學(xué)習(xí)Android 軟件編程有所幫助。
相關(guān)文章
Android實現(xiàn)可點擊的幸運大轉(zhuǎn)盤
這篇文章主要為大家詳細(xì)介紹了Android實現(xiàn)可點擊的幸運大轉(zhuǎn)盤,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-02-02Android將應(yīng)用調(diào)試log信息保存在SD卡的方法
Android將應(yīng)用調(diào)試log信息保存在SD卡的方法大家都知道嗎,下面腳本之家小編給大家分享Android將應(yīng)用調(diào)試log信息保存在SD卡的方法,感興趣的朋友參考下2016-04-04android播放視頻時在立體聲與單聲道之間切換無變化原因分析及解決
使用第三方視頻播放器,有立體聲與單聲道之間切換,發(fā)現(xiàn)切換后無作用,原因是由于在HAL層默認(rèn)沒有處理上層發(fā)的stereo 轉(zhuǎn)mono的命令,具體的解決方法如下2013-06-06Android那兩個你碰不到但是很重要的類之ViewRootImpl
這兩個類就是ActivityThread和ViewRootImpl,之所以說碰不到是因為我們無法通過正常的方式引用這兩個類或者其類的對象,本文就嘗試從幾個我們經(jīng)常接觸的方面先談?wù)刅iewRootImpl,感興趣的可以參考閱讀下2023-05-05Android提高之SQLite分頁讀取實現(xiàn)方法
這篇文章主要介紹了Android的SQLite分頁讀取實現(xiàn)方法,在Android項目開發(fā)中非常實用,需要的朋友可以參考下2014-08-08