RecyclerView添加head和footer

    xiaoxiao2021-03-25  64

    一、实现基本原理

    利用RecyclerView的getItemViewType方法,设置不同的item的类型,在onCreateViewHolder(parent, viewType)方法中根据不同的viewType,设置不同的item的UI。

    二、footer的添加(分页加载)

    2.1 需要添加的footer

    ps:要求文字部分能够动态的替换,如(点击重试、加载完成)

    2.2 判断recyclerview是否滑动到最后一个

    /** * 判断当前RecyclerView是否滑动到最后 * * @param recyclerView * @return */ private boolean isSlideToBottom(RecyclerView recyclerView) { if (recyclerView == null) { return false; } if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() >= recyclerView.computeVerticalScrollRange()) { return true; } return false; }

    2.3 针对分页加载的封装

    2.3.1 希望达成的效果

    需要分页加载的RecyclerView实现封装好的Adapter即可达成分页加载的功能分页加载需要有加载下一页,点击重试,加载完成的基本功能如果所有的item <=10(可指定),不出现footer

    2.3.2 设置加载下一页的条件

    2.3.3 实现代码

    /** * Created by zhufeng on 2016/8/12. * 用于上拉加载的RecyclerView的适配器 */ public abstract class PullToLoadAdapter extends RecyclerView.Adapter { private final int TYPE_FOOTER = -1; private Context mContext; private RecyclerStatus status; /** * 锁住当前状态(防止多次加载) * 在网络加载时locked = true * 需要在网络加载成功后置为false */ private boolean locked = false; /** * 是否出现上拉加载的状态提示条 */ private boolean pullLoadEnable = false; private OnProgressListener onProgressListener; private OnCompleteListener onCompleteListener; public PullToLoadAdapter(Context mContext) { this.mContext = mContext; status = RecyclerStatus.NONE; } @Override public int getItemCount() { if (pullLoadEnable) { return getItemCountChild() + 1; } else { return getItemCountChild(); } } protected abstract int getItemCountChild(); @Override public int getItemViewType(int position) { if (pullLoadEnable && position == getItemCountChild()) { return TYPE_FOOTER; } if (getItemViewTypeChild(position) == TYPE_FOOTER) { throw new IllegalArgumentException("type类型不能与底部条一样,请修改继承类的getItemViewTypeChild方法返回值"); } return getItemViewTypeChild(position); } protected abstract int getItemViewTypeChild(int position); @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == TYPE_FOOTER) { View contentView = LayoutInflater.from(mContext).inflate(R.layout.view_recycler_footer, parent, false); return new FooterViewHolder(contentView); } else { return onCreateViewHolderChild(parent, viewType); } } protected abstract RecyclerView.ViewHolder onCreateViewHolderChild(ViewGroup parent, int viewType); @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof FooterViewHolder) { ((FooterViewHolder) holder).text.setText(status.getName()); if (status == RecyclerStatus.LOADING) { ((FooterViewHolder) holder).progressBar.setVisibility(View.VISIBLE); } else { ((FooterViewHolder) holder).progressBar.setVisibility(View.GONE); } ((FooterViewHolder) holder).text.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onProgressListener != null) { if (status == RecyclerStatus.ERROR) { onProgressListener.tryAgain(); } } if (onCompleteListener != null) { if (status == RecyclerStatus.COMPLETE) { onCompleteListener.onComplete(); } } } }); } else { onBindViewHolderChild(holder, position); } } protected abstract void onBindViewHolderChild(RecyclerView.ViewHolder holder, int position); public void setLocked(boolean locked) { if (this.locked != locked) { this.locked = locked; } } public void setStatus(RecyclerStatus status) { if (this.status != status) { this.status = status; if (this.status == RecyclerStatus.NONE) { pullLoadEnable = false; } else { pullLoadEnable = true; } } } public void setOnProgressListener(OnProgressListener onProgressListener) { this.onProgressListener = onProgressListener; } public void setOnCompleteListener(OnCompleteListener onCompleteListener) { this.onCompleteListener = onCompleteListener; } public void addBindRecyclerView(RecyclerView recyclerView) { recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if (isSlideToBottom(recyclerView)) { if (status == RecyclerStatus.LOADING) { if (!locked) { locked = true; onProgressListener.nextPage(); } } } } }); } /** * 判断当前RecyclerView是否滑动到最后 * * @param recyclerView * @return */ private boolean isSlideToBottom(RecyclerView recyclerView) { if (recyclerView == null) { return false; } if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() >= recyclerView.computeVerticalScrollRange()) { return true; } return false; } private class FooterViewHolder extends RecyclerView.ViewHolder { public TextView text; public ProgressBar progressBar; public FooterViewHolder(View itemView) { super(itemView); text = (TextView) itemView.findViewById(R.id.footer); progressBar = (ProgressBar) itemView.findViewById(R.id.progress_item); } } public interface OnProgressListener { void nextPage(); void tryAgain(); } public interface OnCompleteListener { void onComplete(); } public enum RecyclerStatus { NONE(""), LOADING("加载中"), ERROR("点击重试"), COMPLETE("加载完成"); String name; RecyclerStatus(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } }

    2.3.4 使用示例

    Adapter继承PullToLoadAdapter

    实现onCreateViewHolderChild、onBindViewHolderChild、getItemCountChild、getItemViewTypeChild方法,分别对应RecyclerView.Adapter中的onCreateViewHolder、onBindViewHolder、getItemCount、getItemViewType,用法一样

    实现adapter的setOnProgressListener方法,如:

    mAdapter.setOnProgressListener(new PullToLoadAdapter.OnProgressListener() { @Override public void nextPage() { //进行下一页的数据加载 } @Override public void tryAgain() { //数据加载重试 } }); 数据加载完成时: if(是否加载完全){ if(是否需要显示加载完成){ mAdapter.setStatus(PullToLoadAdapter.RecyclerStatus.COMPLETE); }else{ mAdapter.setStatus(PullToLoadAdapter.RecyclerStatus.NONE); } }else{ mAdapter.setLocked(false); mAdapter.setStatus(PullToLoadAdapter.RecyclerStatus.LOADING); } 数据加载失败时: mAdapter.setStatus(PullToLoadAdapter.RecyclerStatus.ERROR); mAdapter.notifyDataSetChanged();

    三、header的添加

    使用getItemViewType即可,也可以配合PullToLoadAdapter的getItemViewTypeChild使用。这里就不详细说明了。

    四、示例代码下载

    等待上传

    转载请注明原文地址: https://ju.6miu.com/read-35971.html

    最新回复(0)