在ListView中,可以添加头部和尾部,其添加方法也是十分的简单,直接调用listview.addHeaderView(view);listview.addFooterView(view);即可,但在RecyclerView中却没有这样的方法,那么要在RecyclerView中使用这种方法怎么办呢,这就是本文要讲明的地方

原理

查看ListView源代码,得知其头部和尾部,实质上就是对原来的adapter添加了一个头和一个尾,也就是包装了一层,那么我们要在RecyclerView中使用头部和尾部的话,可以按照ListView的方法,依葫芦画瓢做一个头,做一个尾

实现

自定义一个RecyclerView布局,增加头部和尾部的添加方法

public class WrapRecyclerView extends RecyclerView {

    private ArrayList<View> mHeaderViewInfos = new ArrayList<View>();
private ArrayList<View> mFooterViewInfos = new ArrayList<View>();
private Adapter mAdapter; public WrapRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
} public void addHeaderView(View v) {
mHeaderViewInfos.add(v);
if (mAdapter != null) {
if (!(mAdapter instanceof HeaderViewRecyclerAdapter)) {
mAdapter = new HeaderViewRecyclerAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
}
}
} public void addFooterView(View v) {
mFooterViewInfos.add(v);
if (mAdapter != null) {
if (!(mAdapter instanceof HeaderViewRecyclerAdapter)) {
mAdapter = new HeaderViewRecyclerAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
}
}
} @Override
public void setAdapter(Adapter adapter) {
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewRecyclerAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
}
super.setAdapter(mAdapter);
}
}

布局中使用到的适配器

public class HeaderViewRecyclerAdapter extends Adapter {
private Adapter mAdapter;
ArrayList<View> mHeaderViewInfos;
ArrayList<View> mFooterViewInfos; public HeaderViewRecyclerAdapter(ArrayList<View> headerViewInfos,
ArrayList<View> footerViewInfos, Adapter adapter) {
mAdapter = adapter;
if (headerViewInfos == null) {
mHeaderViewInfos = new ArrayList<View>();
} else {
mHeaderViewInfos = headerViewInfos;
}
if (footerViewInfos == null) {
mFooterViewInfos = new ArrayList<View>();
} else {
mFooterViewInfos = footerViewInfos;
}
} @Override
public int getItemCount() {
if (mAdapter != null) {
return getFootersCount() + getHeadersCount() + mAdapter.getItemCount();
} else {
return getFootersCount() + getHeadersCount();
}
} @Override
public void onBindViewHolder(ViewHolder holder, int position) {
int numHeaders = getHeadersCount();
//head
if (position < numHeaders) {
return;
}
//body
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mAdapter != null) {
adapterCount = mAdapter.getItemCount();
if (adjPosition < adapterCount) {
mAdapter.onBindViewHolder(holder, adjPosition);
return;
}
}
//footer
} @Override
public int getItemViewType(int position) {
//判断当前条目是什么类型
int numHeaders = getHeadersCount();
if (position < numHeaders) {
return RecyclerView.INVALID_TYPE;
}
final 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;
} @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//header
if (viewType == RecyclerView.INVALID_TYPE) {
return new HeaderViewHolder(mHeaderViewInfos.get(0));
} else if (viewType == RecyclerView.INVALID_TYPE - 1) {//footer
return new HeaderViewHolder(mFooterViewInfos.get(0));
}
//Footer
return mAdapter.onCreateViewHolder(parent, viewType);
} public int getHeadersCount() {
return mHeaderViewInfos.size();
} public int getFootersCount() {
return mFooterViewInfos.size();
} private static class HeaderViewHolder extends ViewHolder {
public HeaderViewHolder(View view) {
super(view);
}
}
}

在布局文件中使用增加的自定义布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <com.cj5785.wraprecyclerview.WrapRecyclerView
android:id="@+id/wrap_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/> </RelativeLayout>

编写适配器

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private List<String> list;

    public MyAdapter(List<String> list) {
this.list = list;
} class MyViewHolder extends RecyclerView.ViewHolder{
private TextView textView;
public MyViewHolder(View view) {
super(view);
textView = (TextView) view.findViewById(R.id.tv);
}
} @Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.list_item,parent,false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
} @Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.textView.setText(list.get(position));
} @Override
public int getItemCount() {
return list.size();
}
}

适配器的Item布局

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" />

在主活动在调用

public class MainActivity extends AppCompatActivity {

    private WrapRecyclerView wrapRecyclerView;
private LayoutParams params;
private List<String> list;
private MyAdapter adapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wrapRecyclerView = (WrapRecyclerView) findViewById(R.id.wrap_recyclerview);
params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TextView header = new TextView(this);
header.setGravity(Gravity.CENTER);
header.setLayoutParams(params);
header.setText("Header");
wrapRecyclerView.addHeaderView(header);
TextView footer = new TextView(this);
footer.setGravity(Gravity.CENTER);
footer.setLayoutParams(params);
footer.setText("Footer");
wrapRecyclerView.addFooterView(footer);
list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add("item " + i);
}
adapter = new MyAdapter(list);
wrapRecyclerView.setLayoutManager(new LinearLayoutManager(this));
wrapRecyclerView.setAdapter(adapter);
}
}

运行结果

高级UI-RecyclerView头部和尾部添加的更多相关文章

  1. Android 高级UI设计笔记07:RecyclerView 的详解

    1. 使用RecyclerView       在 Android 应用程序中列表是一个非常重要的控件,适用场合非常多,如新闻列表.应用列表.消息列表等等,但是从Android 一出生到现在并没有非常 ...

  2. iOS开发——高级UI&带你玩转UITableView

    带你玩装UITableView 在实际iOS开发中UITableView是使用最多,也是最重要的一个控件,如果你不会用它,那别说什么大神了,菜鸟都不如. 其实关于UItableView事非常简单的,实 ...

  3. 024 如何让html引用公共的头部和尾部(多个html文件公用一个header.html和footer.html)

    前端静态html页面,封装公共的头文件(header:顶部页眉,顶部导航栏等部分)和尾部文件(footer:CopyRight.友情链接等部分) 当前方法:通过load()函数,引入公共头部和尾部文件 ...

  4. Android 高级编程 RecyclerView 控件的使用

    RecyclerView 是Android 新添加的一个用来取代ListView的控件,它的灵活性与可替代性比listview更好. 看一下继承关系: ava.lang.Object    ↳ and ...

  5. table头部、尾部固定;中间内容定高自适应滚动

    table头部.尾部固定;中间内容定高自适应滚动 很多时候,需要使用到表格做数据分析,不管是前端展现,还是后台管理系统节点展现 工作过程中遇到了,作为一个小笔记,备忘! 如下图所示 --------- ...

  6. 用phpcms如何将静态页面制作成企业网站,头部加尾部

    首先,先要准备好这个静态网页的源文件,如图 bs里面是一些css和js的文件,img则是放图片的,文件中的index是网页的首页 运行一下,看看 是这样的 然后打开phpcms文件,上篇博客中有提到, ...

  7. vue引用公用的头部和尾部文件。

    我创建了一个header.vue和fotter.vue,用来做于网站的头部和尾部,每个页面都需要引用这两个,我以组件的方式,来引用这样只需要添加注册的组件就可以了. 第一步.在components文件 ...

  8. iOS开发UI篇—在UIImageView中添加按钮以及Tag的参数说明

    ios开发UI篇—在ImageView中添加按钮以及Tag的参数说明 一.tag参数 一个视图通常都只有一个父视图,多个子视图,在开发中可以通过使用子视图的tag来取出对应的子视图.方法为Viewwi ...

  9. 如何在HTML不同的页面中,共用头部与尾部?

    一.asp语言和PHP语言 首先制作一个头部文件head.asp,或者一个底部文件foot.asp.如主页是index.asp,调用头部代码是在index.asp文件代码的开始位置(第一个标记后面,& ...

随机推荐

  1. sublime 分屏显示 不是插件

    点击 view--layout --- 选择几屏即可(single / columns 2 ....) 快捷键  Alt + Shift + 1/2/3/4  分别对应1 ,2,3,4屏 如何把一个文 ...

  2. 006——C#关闭窗口 添加FormClosing事件

    (一)参考文献:C# 添加FormClosing事件 (二)在  项目名.Designer.cs中的InitializeComponent()添加: this.FormClosing += new S ...

  3. 40 | insert语句的锁为什么这么多?

    在上一篇文章中,我提到 MySQL 对自增主键锁做了优化,尽量在申请到自增 id 以后,就释放自增锁. 因此,insert 语句是一个很轻量的操作.不过,这个结论对于“普通的 insert 语句”才有 ...

  4. GridView修改含有DropDownList控件列的宽度

    GridView进入Edit模式,编辑列动态绑定DropDown List方便客户选择,但当里面的Item过长,不免令界面不美观 正确做法: <asp:TemplateField HeaderT ...

  5. Elasticsearch 索引文档的增删改查

    利用Elasticsearch-head可以在界面上(http://127.0.0.1:9100/)对索引进行增删改查 1.RESTful接口使用方法 为了方便直观我们使用Head插件提供的接口进行演 ...

  6. centos7mongo集群

    1.安装 cat > /etc/yum.repos.d/mongodb.repo << EOF[mongodb-org-3.6]name=MongoDB Repositorybase ...

  7. php关于mysql长连接问题

    1.当 函数 mysql_connect 的前三个参数(server username password)相同,并且第四个参数(new_link)不传递时候,重复调用 mysql_connect 是会 ...

  8. java封装返回结果应用 利用反射机制 返回结果以及错误信息

    //此方法是自己琢磨的,可能有漏洞--符合我的系统目前的需求,大家可以借鉴public ResponseMessage exec (String funname, Object[] params,Ob ...

  9. SpringBoot JPA懒加载异常 - com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy

    问题与分析 某日忽然发现在用postman测试数据时报错如下: com.fasterxml.jackson.databind.JsonMappingException: could not initi ...

  10. class的三元表达式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...