星空网 > 软件开发 > 操作系统

RecyclerView添加头部和底部视图的实现

ListView是有addHeaderView和 addFooterView两个方法的.

但是作为官方推荐的ListView的升级版RecyclerView缺无法实现这两个方法。

那么如果使用RecyclerView实现这两个方法的效果该怎么做呢?

网上查询了很久,试过各种各样的实现方式,终于让我发现一个还不错的实现方法,那么就给大家推荐一下。

项目地址(别人写的,非博主的)https://github.com/jczmdeveloper/XCRecyclerView

我看了下这个源码,很简单,即写了一个继承RecyclerView的控件,自己实现addHeaderView和addFooterView两个方法

RecyclerView添加头部和底部视图的实现images/loading.gif' data-original="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" />RecyclerView添加头部和底部视图的实现
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 ArrayList<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 XCRecyclerView(Context context, AttributeSet attrs) {    this(context, attrs, 0);  }  public XCRecyclerView(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(mDataObserver);  }  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.AdapterDataObserver() {    @Override    public void onChanged() {      mWrapAdapter.notifyDataSetChanged();    }    @Override    public void onItemRangeChanged(int positionStart, int itemCount) {      mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount);    }//    @Override//    public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {//      mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount, payload);//    }    @Override    public void onItemRangeInserted(int positionStart, int itemCount) {      mWrapAdapter.notifyItemRangeInserted(positionStart, itemCount);    }    @Override    public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {      mWrapAdapter.notifyItemMoved(fromPosition, toPosition);    }    @Override    public void onItemRangeRemoved(int positionStart, int itemCount) {      mWrapAdapter.notifyItemRangeRemoved(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 getHeaderCount(){      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 parent, 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 - getHeaderCount();      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

使用方法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);}

注意点:

addHeaderView之后 列表的数据坐标即相应发生变化!即addHeadView一次,列表第一个数据的下坐标+1(0-->1)




原标题:RecyclerView添加头部和底部视图的实现

关键词:ie

ie
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

抖音电商新观察年终特刊:https://www.goluckyvip.com/tag/30689.html
韩国11街:https://www.goluckyvip.com/tag/3069.html
抖音国际版TikTok运营:https://www.goluckyvip.com/tag/30690.html
抖音海外版TikTok运营:https://www.goluckyvip.com/tag/30691.html
抖鹦传媒:https://www.goluckyvip.com/tag/30692.html
斗禾科技:https://www.goluckyvip.com/tag/30693.html
23点聊电商:新质生产力加速数字贸易发展 卓尔智联集团实现营收利润双增长 :https://www.kjdsnews.com/a/1836411.html
南京浦口都有什么好玩的地方 南京浦口都有什么好玩的地方推荐:https://www.vstour.cn/a/363180.html
相关文章
我的浏览记录
最新相关资讯
海外公司注册 | 跨境电商服务平台 | 深圳旅行社 | 东南亚物流