打造用简单,高效,多布局的RecyclerView Adapter

作者 : 开心源码 本文共5921个字,预计阅读时间需要15分钟 发布时间: 2022-05-11 共67人阅读

android快速开发工具类

关于

Fastandrutils 是一套整理修改整合的android开发常使用的工具类。
这样能减少复制粘贴代码,从而减少重复代码,也不使用为了一个常使用的功可以去谷歌百度,让代码更简洁,让开发更高效。
同时希望您的增加完善,让android开发变得更简单。

github地址,感兴趣的话,不妨点赞支持下
个人博客

RecyclerView Adapter 关键的方法

/***可根据position来设置返回viewtype*/public int getItemViewType(int position) /***可根据viewtype来改变layout 创立返回不同的ViewHolder*/public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) /***绑定view 和根据position来获取list item数据*/public void onBindViewHolder(final FViewHolder holder, int position)/***返回总个数*/public int getItemCount()

Adapter关键是要正确用position ,position是绑定数据的关键

设计思路

  • 设置adapter总条数
  • 利使用getItemViewType 的position来定义不同的viewtype
  • 根据viewtype来获取不同的资源id 创立ViewHolder
  • 绑定ViewHolder

1. 如何设置apapter的总条数

因为RecyclerView没有增加header 和footer 的方法所有只可以自己定义,配置apapter的总条数就不可以直接使用 list.size()。

  private int headerSize = 0;  private int footerSize = 0;  @Override    public int getItemCount() {        return datas.size() + headerSize + footerSize;    }

这样设置apapter的总条数就写完了

2. 如何根据position 获取不同的viewtype

返回不同的viewtype 就要使用到getItemViewType(int position) 方法,position 是关键
因为增加了header 和 footer 所有position是没办法对应上list里面的数据了,要解决一下 position 让其对应上list数据

 @Override    public int getItemViewType(int position) {        if (checkRealData(position)) {            return fItemTypeDelegateManager.getItemViewType(null, position);        }//position不符合上面条件的话,就获取list的item的真实数据position - headerSize        return fItemTypeDelegateManager.getItemViewType(datas.get(position - headerSize), position);    }/***检测position,假如position 是符合以下条件就进入header 或者 footer的viewType*/ public boolean checkRealData(int position) {        return (position < headerSize) || position > (datas.size() - 1) + headerSize;    }

headersize 和 footerSize的获取

public void addHeader(@LayoutRes int headerViewRes, final HeaderConvert headerConvert) {        fItemTypeDelegateManager.addDelegate(new FHeaderTypeDelegate<T>(headerSize, headerViewRes) {            @Override            void headerConvert(FViewHolder holder, int position) {                if (headerConvert != null) {                    headerConvert.headerConvert(holder, position);                }            }        });        headerSize++;    }    public void addFooter(@LayoutRes int footerViewRes, final FooterConvert footerConvert) {        fItemTypeDelegateManager.addDelegate(new FFooterTypeDelegate<T>(footerSize, footerViewRes) {            @Override            void footerConvert(FViewHolder holder, int position) {                if (footerConvert != null) {                    footerConvert.footerConvert(holder, position);                }            }        });        footerSize++;    }

没增加一个header 或者footer 他们的大小就会+1

根据position来改变viewtype

首先创立一个FItemTypeDelegate 接口

public interface FItemTypeDelegate<T> {    int getViewType();    boolean isForViewType(T data, int position);    int getViewResouce();    int getSpanSize();    void convert(FViewHolder holder, T t, int position);}

而后创立一个着接口的管理

public class FItemTypeDelegateManager<T> {    SparseArrayCompat<FItemTypeDelegate<T>> delegates = new SparseArrayCompat();    public FItemTypeDelegateManager addDelegate(FItemTypeDelegate<T> delegate) {        if (delegates.get(delegate.getViewType()) != null) {            throw new IllegalArgumentException(                    "already registered for the viewType = "                            + delegate.getViewType());        }        delegates.put(delegate.getViewType(), delegate);        return this;    }    public int getViewResouce(int viewType) {        if (delegates.get(viewType) == null) {            throw new IllegalArgumentException("no this viewType = " + viewType);        }        return delegates.get(viewType).getViewResouce();    }    public int getSpanSize(int viewType) {        if (delegates.get(viewType) == null) {            throw new IllegalArgumentException("no this viewType = " + viewType);        }        return delegates.get(viewType).getSpanSize();    }    public int getItemViewType(T item, int postion) {        int delegatesCount = delegates.size();        for (int i = 0; i < delegatesCount; i++) {            FItemTypeDelegate<T> delegate = delegates.valueAt(i);            if (delegate.isForViewType(item, postion)) {                return delegate.getViewType();            }        }        throw new IllegalArgumentException(                "No FItemTypeDelegate added ");    }    public void onBindViewHolder(FViewHolder holder, T item, int position, int viewType) {        if (delegates.get(viewType) == null) {            throw new IllegalArgumentException("no this viewType = " + viewType);        }        delegates.get(viewType).convert(holder, item, position);    }}

根据不同的需求实现FItemTypeDelegate接口即可以完成viewType的改变了,下面是header的

public abstract class FHeaderTypeDelegate<T> implements FItemTypeDelegate<T> {    private int viewType;    private int viewRes;    public FHeaderTypeDelegate(int viewType, @LayoutRes int viewRes) {        this.viewType = viewType;        this.viewRes = viewRes;    }/***定义header的type*/    @Override    public int getViewType() {        return (viewType + 1) * 1000;    }/***判断这次的position能否是header*/    @Override    public boolean isForViewType(T data, int position) {        return position == viewType;    }/***返回资源id*/    @Override    public int getViewResouce() {        return viewRes;    }    @Override    public int getSpanSize() {        return 0;    }/***绑定ui*/    @Override    public void convert(FViewHolder holder, T t, int position) {        headerConvert(holder, position);    }    abstract void headerConvert(FViewHolder holder, int position);}

3. 如何根据不同的viewType创立不同的viewholder

onCreateViewHolder(ViewGroup parent, int viewType) 方法来创立返回viewholer

    @Override    public FViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        return FViewHolder.createViewHolder(context, parent, fItemTypeDelegateManager.getViewResouce(viewType));    }

根据不同的viewType在fItemTypeDelegateManager类里检索出资源id

 public int getViewResouce(int viewType) {        if (delegates.get(viewType) == null) {            throw new IllegalArgumentException("no this viewType = " + viewType);        }        return delegates.get(viewType).getViewResouce();    }

4.如何绑定ViewHolder

关键还是position 因为有header 和 footer的存在,要解决position ,拿到list真实的position数据

  @Override    public void onBindViewHolder(final FViewHolder holder, int position) {//判断假如是header和footer的话返回null,假如是list的话就position - headerSize获取真实数据        T data = checkRealData(position) ? null : datas.get(position - headerSize);        fItemTypeDelegateManager.onBindViewHolder(holder, data, position, getItemViewType(position));        if (onItemClickListener != null) {            holder.getConvertView().setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    if (checkRealData(holder.getLayoutPosition())) {                        return;                    }                    onItemClickListener.onItemClick(null, v, holder.getLayoutPosition() - headerSize, holder.getItemId());                }            });            holder.getConvertView().setOnLongClickListener(new View.OnLongClickListener() {                @Override                public boolean onLongClick(View v) {                    if (checkRealData(holder.getLayoutPosition())) {                        return false;                    }                    if (onItemLongClickListener != null) {                        return onItemLongClickListener.onItemLongClick(null, v, holder.getLayoutPosition() - headerSize, holder.getItemId());                    }                    return false;                }            });        }    }

以上就是 用简单,高效,多布局的RecyclerView Adapter 思路就编码

附上github地址

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 打造用简单,高效,多布局的RecyclerView Adapter

发表回复