Android设置RecyclerView的Header和Footer
getItemViewType方法设置相应条目的显示位置
//定义常量 判断RecyclerView具体的加载方式
public static final int TYPE_NORMAL = 0; //说明是不带有header和footer的
public static final int TYPE_HEADER = 1; //说明是带有Header的
public static final int TYPE_FOOTER = 2; //说明是带有Footer的
//将视图同条目位置进行匹配
@Override
public int getItemViewType(int position) {
//如果都不存在 返回的视图类型为常规适配器 正常就可 不需要特殊加载
if(mHeaderView == null && mFooterView == null){
return TYPE_NORMAL;
}
//设置不同View视图的位置 (有头时)且是在第一个条目时 返回对应的布局
if(mHeaderView != null && position == 0){
return TYPE_HEADER;
}
//设置不同View视图的位置 (有脚时)且在最后一个条目时 返回对应的布局
if(mFooterView != null && position == getItemCount() - 1){
return TYPE_FOOTER;
}
return TYPE_NORMAL;
}
ViewHolder类返回不同的视图
//根据加载方式 来加载对应的视图 RecyclerView必然加载
//首先要有相对应的视图
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//
if(mHeaderView != null && viewType == TYPE_HEADER){
return new ViewHolder(mHeaderView);
}
if (mFooterView != null && viewType == TYPE_FOOTER){
return new ViewHolder(mFooterView);
}
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_floor,parent,false);
return new ViewHolder(view);
}
onBindViewHolder方法对不同条目做出不同的处理
//正常方式处理
if(getItemViewType(position) == TYPE_NORMAL){
//判断类型是否相匹配
if(holder instanceof ViewHolder){
//注意此时第0个条目已经被占据 因此要从position-1 来加载集合数据
FloorBean.DataBean dataBean = message.get(position-1);
Glide.with(context).load(dataBean.getFloor_title().getImage_src()).into(holder.getImgTitle());
List<FloorBean.DataBean.Commodity> product_list = dataBean.getProduct_list();
ArrayList<String> imgUilList = new ArrayList<>();
for(FloorBean.DataBean.Commodity commodity : product_list){
imgUilList.add(commodity.getImage_src());
}
ImageView[] imgs = {holder.getImgOne(),holder.getImgTwo(),holder.getImgThree(),holder.getImgFour(),holder.getImgFive()};
for(int i = 0 ; i<imgs.length ; i++){
Glide.with(context).load(imgUilList.get(i)).into(imgs[i]);
}
return;
}
return;
}else if(getItemViewType(position) == TYPE_HEADER){
//一般不建议在适配器里处理头和脚视图 直接在传递之前进行处理
return;
}else {
return;
}
getItemCount()方法根据不同的返回设置相对应的条目数
这个就不写注释了
@Override
public int getItemCount() {
if(mHeaderView == null && mFooterView == null){
return message.size();
}else if(mHeaderView == null && mFooterView != null){
return message.size() + 1;
}else if (mHeaderView != null && mFooterView == null){
return message.size() + 1;
}else {
return message.size() + 2;
}
}
在Activity或Fragment中设置加载的头和脚
private void initAdapter(List<FloorBean.DataBean> message) {
recyclerView = fragmentView.findViewById(R.id.rec_floor);
floorAdapter = new FloorAdapter();
floorAdapter.setContext(getContext());
floorAdapter.setMessage(message);
//设置对应的头脚
floorAdapter.setmHeaderView(setHeaderView());
View foot = LayoutInflater.from(getContext()).inflate(R.layout.test_ll, null, false);
floorAdapter.setmFooterView(foot);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(floorAdapter);
}
private View setHeaderView() {
View header = LayoutInflater.from(getContext()).inflate(R.layout.header_front, null, false);
mXBanner = header.findViewById(R.id.xbanner);
mImgClassification = header.findViewById(R.id.img_classification);
mImgSpike = header.findViewById(R.id.img_spike);
mImgShopping = header.findViewById(R.id.img_shopping);
mImgBaby = header.findViewById(R.id.img_baby);
layoutHeader = header.findViewById(R.id.header_front);
DisplayMetrics dm = getResources().getDisplayMetrics();
int height = dm.heightPixels;
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) layoutHeader.getLayoutParams();
params.height = (int) (height / 2.2);
layoutHeader.setLayoutParams(params);
return header;
}
适配器完整代码
为什么会纠结不加载头和脚会出现数组越界异常呢?你既然费这么大力写了那么多 不就是为了加个头和脚吗?
package com.qingsu.ugrowshopping.vm.daapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.qingsu.ugrowshopping.R;
import com.qingsu.ugrowshopping.vm.bean.BannerBean;
import com.qingsu.ugrowshopping.vm.bean.FloorBean;
import java.util.ArrayList;
import java.util.List;
public class FloorAdapter extends RecyclerView.Adapter<FloorAdapter.ViewHolder>{
public static final int TYPE_NORMAL = 0; //说明是不带有header和footer的
public static final int TYPE_HEADER = 1; //说明是带有Header的
public static final int TYPE_FOOTER = 2; //说明是带有Footer的
private List<FloorBean.DataBean> message;
private Context context;
//传入视图
private View mHeaderView;
private View mFooterView;
public View getmHeaderView() {
return mHeaderView;
}
public void setmHeaderView(View mHeaderView) {
this.mHeaderView = mHeaderView;
notifyItemInserted(0);
}
public View getmFooterView() {
return mFooterView;
}
public void setmFooterView(View mFooterView) {
this.mFooterView = mFooterView;
notifyItemInserted(getItemCount()-1);
}
@Override
//定义常量 判断RecyclerView具体的加载方式
public int getItemViewType(int position) {
//如果都不存在 返回的视图类型为常规适配器 正常就可 不需要特殊加载
if(mHeaderView == null && mFooterView == null){
return TYPE_NORMAL;
}
//设置不同View视图的位置 (有头时)且是在第一个条目时 返回对应的布局
if(mHeaderView != null && position == 0){
return TYPE_HEADER;
}
//设置不同View视图的位置 (有脚时)且在最后一个条目时 返回对应的布局
if(mFooterView != null && position == getItemCount() - 1){
return TYPE_FOOTER;
}
return TYPE_NORMAL;
}
public void setMessage(List<FloorBean.DataBean> message) {
this.message = message;
}
public void setContext(Context context) {
this.context = context;
}
public class ViewHolder extends RecyclerView.ViewHolder{
private final ImageView imgTitle,imgOne,imgTwo,imgThree,imgFour,imgFive;
public ViewHolder(@NonNull View itemView) {
super(itemView);
imgTitle = itemView.findViewById(R.id.img_title);
imgOne = itemView.findViewById(R.id.img_commodityone);
imgTwo = itemView.findViewById(R.id.img_commoditytwo);
imgThree = itemView.findViewById(R.id.img_commoditythree);
imgFour = itemView.findViewById(R.id.img_commodityfour);
imgFive = itemView.findViewById(R.id.img_commodityfive);
}
public ImageView getImgTitle() {
return imgTitle;
}
public ImageView getImgOne() {
return imgOne;
}
public ImageView getImgTwo() {
return imgTwo;
}
public ImageView getImgThree() {
return imgThree;
}
public ImageView getImgFour() {
return imgFour;
}
public ImageView getImgFive() {
return imgFive;
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//
if(mHeaderView != null && viewType == TYPE_HEADER){
return new ViewHolder(mHeaderView);
}
if (mFooterView != null && viewType == TYPE_FOOTER){
return new ViewHolder(mFooterView);
}
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_floor,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
//正常方式处理
if(getItemViewType(position) == TYPE_NORMAL){
//判断类型是否相匹配
if(holder instanceof ViewHolder){
//注意此时第0个条目已经被占据 因此要从position-1 来加载集合数据
FloorBean.DataBean dataBean = message.get(position-1);
Glide.with(context).load(dataBean.getFloor_title().getImage_src()).into(holder.getImgTitle());
List<FloorBean.DataBean.Commodity> product_list = dataBean.getProduct_list();
ArrayList<String> imgUilList = new ArrayList<>();
for(FloorBean.DataBean.Commodity commodity : product_list){
imgUilList.add(commodity.getImage_src());
}
ImageView[] imgs = {holder.getImgOne(),holder.getImgTwo(),holder.getImgThree(),holder.getImgFour(),holder.getImgFive()};
for(int i = 0 ; i<imgs.length ; i++){
Glide.with(context).load(imgUilList.get(i)).into(imgs[i]);
}
return;
}
return;
}else if(getItemViewType(position) == TYPE_HEADER){
//一般不建议在适配器里处理头和脚视图 直接在传递之前进行处理
return;
}else {
return;
}
}
@Override
public int getItemCount() {
if(mHeaderView == null && mFooterView == null){
return message.size();
}else if(mHeaderView == null && mFooterView != null){
return message.size() + 1;
}else if (mHeaderView != null && mFooterView == null){
return message.size() + 1;
}else {
return message.size() + 2;
}
}
}
效果
时尚女装上面的是个头
下面的一张图片是个脚