RecyclerView: add the header and bottom views, and recyclerview
ListView has two methods: addHeaderView and addFooterView.
However, the upgraded version of ListView RecyclerView, which is officially recommended, cannot be implemented.
So what should we do if we use RecyclerView to implement the effects of these two methods?
I have been searching the Internet for a long time. I tried various implementation methods and finally found a good implementation method. I would like to recommend it to you.
Project address (written by others, non-blogger) https://github.com/jczmdeveloper/XCRecyclerView
After reading the source code, I wrote a control that inherits the RecyclerView and implemented it myself.AddHeaderView and
AddFooterView
Package com.xqx.com. recyclerviewheaderdemo; import android. content. context; import android. support. v7.widget. recyclerView; import android. util. attributeSet; import android. util. log; import android. view. view; import android. view. viewGroup; import java. util. arrayList; import java. util. list; public class XCRecyclerView extends RecyclerView {private ArrayList <View> mHeaderViews = new ArrayList <> (); private Arra YList <View> mFooterViews = new ArrayList <> (); private RecyclerView. adapter mAdapter; private RecyclerView. adapter mWrapAdapter; private static final int TYPE_HEADER =-101; private static final int TYPE_FOOTER =-102; private static final int TYPE_LIST_ITEM =-103; public XCRecyclerView (Context context) {this (context, null);} public xcreatererview (Context context, AttributeSet attrs) {this (con Text, attrs, 0);} public xcreatererview (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle); init (context );} private void init (Context context) {}@ Override public void setAdapter (Adapter adapter) {mAdapter = adapter; mWrapAdapter = new WrapAdapter (mHeaderViews, mFooterViews, Adapter); super. setAdapter (mWrapAdapter); mAdapter. registerAdapterDataObserver (mDataObs Erver);} public void addHeaderView (View view) {mHeaderViews. clear (); mHeaderViews. add (view);} public void addFooterView (View view) {mFooterViews. clear (); mFooterViews. add (view);} public int getHeaderViewsCount () {return mHeaderViews. size ();} public int getFooterViewsCount () {return mFooterViews. size ();} private final RecyclerView. adapterDataObserver mDataObserver = new RecyclerView. adapterDat AObserver () {@ Override public void onChanged () {mWrapAdapter. notifyDataSetChanged () ;}@ Override public void onItemRangeChanged (int positionStart, int itemCount) {mWrapAdapter. policyitemrangechanged (positionStart, itemCount);} // @ Override // public void onItemRangeChanged (int positionStart, int itemCount, Object payload) {// mWrapAdapter. policyitemrangechanged (positionStart, itemCount, payload); //} @ Override public void onItemRangeInserted (int positionStart, int itemCount) {mWrapAdapter. policyitemrangeinserted (positionStart, itemCount) ;}@ Override public void onItemRangeMoved (int fromPosition, int toPosition, int itemCount) {mWrapAdapter. policyitemmoved (fromPosition, toPosition);} @ Override public void onItemRangeRemoved (int positionStart, int itemCount) {mWrapAdapter. notifyItemRa NgeRemoved (positionStart, itemCount) ;}}; private class WrapAdapter extends RecyclerView. adapter <ViewHolder> {private Adapter mAdapter; private List <View> mHeaderViews; private List <View> mFooterViews; public WrapAdapter (List <View> headerViews, List <View> footerViews, adapter adapter) {this. mAdapter = adapter; this. mHeaderViews = headerViews; this. mFooterViews = footerViews;} public int getHeaderC Ount () {return this. mHeaderViews. size ();} public int getFooterCount () {return this. mFooterViews. size () ;}public boolean isHeader (int position) {return position >=0 & position <this. mHeaderViews. size ();} public boolean isFooter (int position) {return position <getItemCount () & position> = getItemCount ()-this. mFooterViews. size () ;}@ Override public ViewHolder onCreateViewHolder (ViewGroup pa Rent, int viewType) {if (viewType = TYPE_HEADER) {return new CustomViewHolder (this. mHeaderViews. get (0);} else if (viewType = TYPE_FOOTER) {return new CustomViewHolder (this. mFooterViews. get (0);} else {return this. mAdapter. onCreateViewHolder (parent, viewType) ;}@ Override public void onBindViewHolder (ViewHolder holder, int position) {if (isHeader (position) return; if (isFooter (position) return; Int rePosition = position-getHeaderCount (); int itemCount = this. mAdapter. getItemCount (); if (this. mAdapter! = Null) {if (rePosition <itemCount) {Log. v ("czm", "rePosition/itemCount =" + rePosition + "/" + itemCount); this. mAdapter. onBindViewHolder (holder, rePosition); return ;}}@ Override public long getItemId (int position) {if (this. mAdapter! = Null & position> = getHeaderCount () {int rePosition = position-getHeaderCount (); int itemCount = this. mAdapter. getItemCount (); if (rePosition <itemCount) {return this. mAdapter. getItemId (rePosition) ;}} return-1 ;}@ Override public int getItemViewType (int position) {if (isHeader (position) {return TYPE_HEADER ;} if (isFooter (position) {return TYPE_FOOTER;} int rePosition = position-get HeaderCount (); int itemCount = this. mAdapter. getItemCount (); if (rePosition <itemCount) {return this. mAdapter. getItemViewType (position);} return TYPE_LIST_ITEM;} @ Override public int getItemCount () {if (this. mAdapter! = Null) {return getHeaderCount () + getFooterCount () + this. mAdapter. getItemCount ();} else {return getHeaderCount () + getFooterCount () ;}@override public void registerAdapterDataObserver (AdapterDataObserver observer) {if (this. mAdapter! = Null) {this. mAdapter. registerAdapterDataObserver (observer) ;}}@ Override public void unregisterAdapterDataObserver (AdapterDataObserver observer) {if (this. mAdapter! = Null) {this. mAdapter. unregisterAdapterDataObserver (observer) ;}} private class CustomViewHolder extends ViewHolder {public CustomViewHolder (View itemView) {super (itemView );}}}}XCRecyclerView
Usage instructions are also clearly written in github
private MyAdapter mAdapter;private XCRecyclerView mRecyclerView;private List<String> mData;private View mHeaderView;private View mFooterView;@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mData = new ArrayList<String>(); for(int i = 0; i < 10 ;i++){ mData.add("item_" + i); } mAdapter = new MyAdapter(mData); mRecyclerView = (XCRecyclerView) findViewById(R.id.recycler_view); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); mHeaderView = LayoutInflater.from(this).inflate(R.layout.layout_header,mRecyclerView,false); mFooterView = LayoutInflater.from(this).inflate(R.layout.layout_footer,mRecyclerView,false); mRecyclerView.addHeaderView(mHeaderView); mRecyclerView.addFooterView(mFooterView); mRecyclerView.setAdapter(mAdapter);}
Note:
The data coordinates of the list after addHeaderView are changed accordingly! That is, addHeadView is run once. the coordinate of the first data in the list is + 1 (0 --> 1)