使用RecyclerView添加Header和Footer的方法
RecyclerView与ListView原理是类似的:都是仅仅维护少量的View并且可以展示大量的数据集。RecyclerView用以下两种方式简化了数据的展示和处理: 使用LayoutManager来确定每一个item的排列方式。 为增加和删除项目提供默认的动画效果。 RecyclerView虽然作为ListView的替代者有着较好的性能提升,但是ListView的一些常用功能却没有提供,比如我们平时会经常用到的addHeaderView,addFooterView,既然RecyclerView没有提供这个方法,我们应该如何为列表添加头部和底部呢?通过看ListView的源码可以知道ListView的添加Header和Footer是靠Adapter里面动态添加的,所以我们按照这个思路也给RecyclerView添加HeaderView和FooterView,先看一下效果 如果你还不了解RecyclerView如何使用,可以看一下前几篇博文 RecyclerView的使用之HelloWorld RecyclerView的使用之多Item布局的加载 RecyclerView实现添加HeaderView和FooterView的核心就是在Adapter里面的onCreateViewHolder根据viewType来判断是列表项还是HeaderView来分别加载不同的布局文件,当然viewType的判断规则也是由我们定义的,废话不多说,看一下具体的实现效果。 1:Gradle配置 build.gradle compile 'com.android.support:recyclerview-v7:23.1.1' compile 'com.android.support:cardview-v7:23.1.1' 2:主布局文件 activity_main.xml 很简单里面一个RecyclerView <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/rv_list" /> </LinearLayout> 3:列表项布局 rv_item.xml 外面一个CardView的卡片式容器里面一个TextView <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="8dp" android:id="@+id/cv_item" android:foreground="?android:attr/selectableItemBackground" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv_item_text" android:text="test" android:layout_margin="8dp" /> </LinearLayout> </android.support.v7.widget.CardView> 4:列表头部布局 rv_header.xml <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="8dp" android:id="@+id/cv_item" android:foreground="?android:attr/selectableItemBackground" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp" card_view:cardBackgroundColor="#4CAF50" > <LinearLayout android:layout_width="match_parent" android:layout_height="150dp" > <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="Header" android:textSize="30sp" android:textColor="#ffffff" android:gravity="center" /> </LinearLayout> </android.support.v7.widget.CardView> 5:列表底部布局 rv_footer.xml <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="8dp" android:id="@+id/cv_item" android:foreground="?android:attr/selectableItemBackground" card_view:cardCornerRadius="4dp" card_view:cardElevation="4dp" card_view:cardBackgroundColor="#E91E63" > <LinearLayout android:layout_width="match_parent" android:layout_height="150dp" > <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="Footer" android:textSize="30sp" android:textColor="#ffffff" android:gravity="center" /> </LinearLayout> </android.support.v7.widget.CardView> 6:*HeaderBottomAdapter.java,RecyclerView的Adapter,在getItemViewType方法里面判断了当前Item的类型,然后在onCreateViewHolder跟据item的类型分别加载不同的布局以实现HeaderView和FooterView,其他方法的含义可以参考注释 import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; /** * Created by Lijizhou on 2016/2/24. * Blog:http://blog.csdn.net/leejizhou * QQ:3107777777 */ public class HeaderBottomAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { //item类型 public static final int ITEM_TYPE_HEADER = 0; public static final int ITEM_TYPE_CONTENT = 1; public static final int ITEM_TYPE_BOTTOM = 2; //模拟数据 public String [] texts={"java","python","C++","Php",".NET","js","Ruby","Swift","OC"}; private LayoutInflater mLayoutInflater; private Context mContext; private int mHeaderCount=1;//头部View个数 private int mBottomCount=1;//底部View个数 public HeaderBottomAdapter(Context context) { mContext = context; mLayoutInflater = LayoutInflater.from(context); } //内容长度 public int getContentItemCount(){ return texts.length; } //判断当前item是否是HeadView public boolean isHeaderView(int position) { return mHeaderCount != 0 && position < mHeaderCount; } //判断当前item是否是FooterView public boolean isBottomView(int position) { return mBottomCount != 0 && position >= (mHeaderCount + getContentItemCount()); } //判断当前item类型 @Override public int getItemViewType(int position) { int dataItemCount = getContentItemCount(); if (mHeaderCount != 0 && position < mHeaderCount) { //头部View return ITEM_TYPE_HEADER; } else if (mBottomCount != 0 && position >= (mHeaderCount + dataItemCount)) { //底部View return ITEM_TYPE_BOTTOM; } else { //内容View return ITEM_TYPE_CONTENT; } } //内容 ViewHolder public static class ContentViewHolder extends RecyclerView.ViewHolder { private TextView textView; public ContentViewHolder(View itemView) { super(itemView); textView=(TextView)itemView.findViewById(R.id.tv_item_text); } } //头部 ViewHolder public static class HeaderViewHolder extends RecyclerView.ViewHolder { public HeaderViewHolder(View itemView) { super(itemView); } } //底部 ViewHolder public static class BottomViewHolder extends RecyclerView.ViewHolder { public BottomViewHolder(View itemView) { super(itemView); } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) { if (viewType ==ITEM_TYPE_HEADER) { return new HeaderViewHolder(mLayoutInflater.inflate(R.layout.rv_header,parent,false)); } else if (viewType == mHeaderCount) { return new ContentViewHolder(mLayoutInflater.inflate(R.layout.rv_item,false)); } else if (viewType == ITEM_TYPE_BOTTOM) { return new BottomViewHolder(mLayoutInflater.inflate(R.layout.rv_footer,false)); } return null; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder,int position) { if (holder instanceof HeaderViewHolder) { } else if (holder instanceof ContentViewHolder) { ((ContentViewHolder) holder).textView.setText(texts[position - mHeaderCount]); } else if (holder instanceof BottomViewHolder) { } } @Override public int getItemCount() { return mHeaderCount + getContentItemCount() + mBottomCount; } } 7:最后一步,MainActivity.java import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private HeaderBottomAdapter adapter; GridLayoutManager gridLayoutManager; LinearLayoutManager layoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView=(RecyclerView)findViewById(R.id.rv_list); //List布局 layoutManager=new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(layoutManager); mRecyclerView.setAdapter(adapter=new HeaderBottomAdapter(this)); //Grid布局 // gridLayoutManager=new GridLayoutManager(MainActivity.this,2); // mRecyclerView.setLayoutManager(gridLayoutManager);//这里用线性宫格显示 类似于grid view // mRecyclerView.setAdapter(adapter=new HeaderBottomAdapter(this)); // // // gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { // @Override // public int getSpanSize(int position) { // return (adapter.isHeaderView(position) || adapter.isBottomView(position)) ? gridLayoutManager.getSpanCount() : 1; // } // }); } } 这里注意一点,如果你的RecyclerView使用Grid类型列表在设置Adapter后需要调用这个方法,根据当前Item类型来判断占据的横向格数,这也是Adapter里面实现isHeaderView和isBottomView的缘故 gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return (adapter.isHeaderView(position) || adapter.isBottomView(position)) ? gridLayoutManager.getSpanCount() : 1; } }); Ok,RecyclerView添加Header和Footer就这样轻松实现了,你也可以把Adapter再次封装更有利于日常的开发。 关于使用RecyclerView添加Header和Footer的方法就给大家介绍到这里,希望对大家有所帮助! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Spring Boot打包war jar 部署tomcat
- [转帖]关于Java中SQL语句的拼接规则
- java – 在getClass()文档中,“被调用的表达式的静态类型的
- java – Kotlin Stream peek(…)方法
- java – 如何学习JSP / MVC,以前在ASP.Net MVC中的经验?
- java 去除空格、标点符号
- java.util.zip.ZipException:无效的CEN头(不良签名)
- java – SWT:如何进行高质量图像调整大小
- java – 在应用程序运行时更新Spring Boot属性的更好方法
- java – Hibernate Bi-Directional多对多关联创建重复