在RecyclerView中添加页眉和页脚

时间:2019-01-13 10:26:59

标签: android android-recyclerview

我在RecyclerView中添加了页眉和页脚,当屏幕启动时,出现了页眉,但是当我滚动后,recycler view活动的最后一项被破坏后却不显示页脚。当数据绑定到回收者工具的普通列表项时,错误发生在onBindViewHolder中。

这是我的适配器

package com.tecishsol.salmon.Adapter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.tecishsol.salmon.Model.ServicesPreferencesModel;
import com.tecishsol.salmon.R;
import com.tecishsol.salmon.Viewholder.FooterViewHolder;
import com.tecishsol.salmon.Viewholder.HeaderViewHolder;
import com.tecishsol.salmon.Viewholder.ServicesPreferencesViewHolder;

import java.util.List;

public class ServicesPreferencesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<ServicesPreferencesModel> data;
    private Context context;
    private LayoutInflater inflater;
    private ServicesPreferencesModel current;

    private static final int TYPE_HEADER = 0;
    private static final int TYPE_FOOTER = 1;
    private static final int TYPE_ITEM = 2;

    public ServicesPreferencesAdapter(Context context, List<ServicesPreferencesModel> data) {
        this.context = context;
        this.inflater = LayoutInflater.from(context);
        this.data = data;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        if (viewType == TYPE_ITEM) {
            //Inflating recycle view item layout
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_preference, parent, false);
            return new ServicesPreferencesViewHolder(itemView);
        } else if (viewType == TYPE_HEADER) {
            //Inflating header view
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_header_sp, parent, false);
            return new HeaderViewHolder(itemView);
        } else if (viewType == TYPE_FOOTER) {
            //Inflating footer view
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_sp, parent, false);
            return new FooterViewHolder(itemView);
        } else return null;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {

        if (holder instanceof HeaderViewHolder) {
            HeaderViewHolder headerHolder = (HeaderViewHolder) holder;
        } else if (holder instanceof FooterViewHolder) {
            FooterViewHolder footerHolder = (FooterViewHolder) holder;
            footerHolder.btnAddPrefSp.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(context, "You clicked at Footer View", Toast.LENGTH_SHORT).show();
                }
            });
        } else if (holder instanceof ServicesPreferencesViewHolder) {

            current = data.get(position);
            ServicesPreferencesViewHolder servicesPreferencesViewHolder = (ServicesPreferencesViewHolder) holder;

            servicesPreferencesViewHolder.tvIndex.setText(current.getIndex());
            servicesPreferencesViewHolder.tvFacility.setText(current.getFacility());
            servicesPreferencesViewHolder.tvClose.setText(current.getHowCloseNeeded());
            servicesPreferencesViewHolder.tvComments.setText(current.getComments());
            servicesPreferencesViewHolder.tvImportanceLevelStatus.setText(current.getImportanceLevel());
            servicesPreferencesViewHolder.tvImportanceStatus.setText(current.getImportance());
        }
    }


    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemCount() {
        return data.size() + 2;
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return TYPE_HEADER;
        } else if (position == data.size() + 1) {
            return TYPE_FOOTER;
        }
        return TYPE_ITEM;
    }

}

1 个答案:

答案 0 :(得分:0)

如果我没有给出实际的例外,我所能提供的就是我认为的错误。

Recyclerview适配器必须中继以正确顺序放置的项目,并且由于您说它还​​有两个其他项目,因此它假定该项目并且实际上包含正确的项目。

当您说位置0处的项目是标题时,您将整个列表向下移动一位,而不实际处理最后一个项目并递减计数,这将导致最后一个项目出现问题。

例如,您将在位置1而不是位置0访问第一项

我建议您通过创建所有项目都实现的父数据模型,将页眉和页脚的实现更改为列表的一部分,并根据该列表中当前使用的数据模型来检查不基于位置。

因此您可以更改此:

@Override
public int getItemCount() {
    return data.size() + 2;
}

@Override
public int getItemViewType(int position) {
    if (position == 0) {
        return TYPE_HEADER;
    } else if (position == data.size() + 1) {
        return TYPE_FOOTER;
    }
    return TYPE_ITEM;
}

收件人:

@Override
public int getItemCount() {
    return data.size();
}

@Override
public int getItemViewType(int position) {
    ServicesPreferencesModel model = data[position]
    if (model instanceOf HeaderDataModel) {
        return TYPE_HEADER;
    } else if (model instanceOf FooterDataModel) {
        return TYPE_FOOTER;
    }
    return TYPE_ITEM;
}

您甚至可以更改它,而不是返回TYPE,而返回与所需类型关联的布局

您可以查看Gencycler,它是我创建的库,可以在编译时为您生成所有代码,并且它支持页眉和页脚。您不需要使用它(应该使用),而只是看一下它如何处理多视图类型的实现,您可以学到很多东西