文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android RecyclerView添加头部和底部的方法

2022-06-06 08:26

关注

如果只是想添加头部,可是使用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设置了LayoutManager之后调用。

目前该库适用于LinearLayoutManager,StaggeredGridLayoutManager和GridLayoutManager布局的RecyclerViews。只支持垂直布局LayoutManager。如果你打算在RecyclerView中使用setOnScrollListener(…)方法,确保在setOnScrollListener(…)的attachTo(…)方法之前使用。

当然我们也可以自己写一个添加头部和底部的RecyclerView。它实现的基本原理也是通过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没有实现,下面我们就来看下RecyclerWrapAdapter,这个也是实现添加头部和尾部的关键。


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给头部,当position小于头部总数的时候,
  //我们返回头部view。再判断原Adapter 的 count 与当前 position 
  // 的差值来比较,是调用原 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给头部,当position小于头部总数的时候,
  //我们返回头部类型。再判断原Adapter 的 count 与当前 position 
  // 的差值来比较,是调用原 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);
  }
 }
}

我们还可以实现一个接口,来调用RecyclerWrapAdapter对象:


public interface WrapperAdapter {
 public RecyclerView.Adapter getWrappedAdapter() ;
}

这样我们就可以把RecyclerView布局改成WrapRecyclerView就可以了,然后调用addHeaderView或者addFooterView就可以添加头部和尾部了。

您可能感兴趣的文章:Android中封装RecyclerView实现添加头部和底部示例代码Recyclerview添加头布局和尾布局、item点击事件详解Android实现RecyclerView添加分割线的简便方法Android RecyclerView添加头部和底部实例详解使用RecyclerView添加Header和Footer的方法Android实战RecyclerView头部尾部添加方法示例


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯