资讯专栏INFORMATION COLUMN

RecyclerView.Adapter优化了吗?

lmxdawn / 1722人阅读

摘要:还可以添加一些常用的方法如代码我已经上传到上了,有兴趣的同学或者一起共同将它完成的更完善送大家一句我非常喜欢的话不分享谁与你共享呢源码地址传送门

昨天写了一篇「还在用ListView?」讲的内容是RecyclerView的使用技巧以及一些常用的开源库,有朋友反馈“我已经在用recyclerview了”,那么如何让它更好用呢?此时我想到了优化RecyclerView.Adapter,因为在RecyclerView还没出来之前我就写过一篇「ListView之Adapter优化」,通过这篇文章的优化思路可以在原来的代码上修改部分代码用在优化RecyclerView.Adapter上,一如既往的好用。

本次主要讲两个方面的优化

精简代码

扩展功能


精简代码

正常没优化的写法:

public class DefAdpater extends RecyclerView.Adapter {
    private final List sampleData = DataServer.getSampleData();
    private Context mContext;
    public DefAdpater(Context context) {
        mContext = context;
    } 
   @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View item = LayoutInflater.from(parent.getContext()).inflate(R.layout.tweet, parent, false);
        return new ViewHolder(item);
    }
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Status status = sampleData.get(position);
        holder.name.setText(status.getUserName());
        holder.text.setText(status.getText());
        holder.date.setText(status.getCreatedAt());
        Picasso.with(mContext).load(status.getUserAvatar()).into(holder.avatar);
        holder.rt.setVisibility(status.isRetweet() ? View.VISIBLE : View.GONE);
    }
    @Override
    public int getItemCount() {
        return sampleData.size();
    }
    public static class ViewHolder extends RecyclerView.ViewHolder {
        private ImageView avatar;
        private ImageView rt;
        private TextView name;
        private TextView date;
        private TextView text;
        public ViewHolder(View itemView) {
            super(itemView);
            text = (TextView) itemView.findViewById(R.id.tweetText);
            name = (TextView) itemView.findViewById(R.id.tweetName);
            date = (TextView) itemView.findViewById(R.id.tweetDate);
            avatar = (ImageView) itemView.findViewById(R.id.tweetAvatar);
            rt = (ImageView) itemView.findViewById(R.id.tweetRT);
        }
    }
}

优化后,是这样的:

public class QuickAdapter extends BaseQuickAdapter {
    public QuickAdapter(Context context) {
        super(context, R.layout.tweet, DataServer.getSampleData());
    }
    @Override
    protected void convert(BaseAdapterHelper helper, Status item) {
        helper.setText(R.id.tweetName, item.getUserName())
                .setText(R.id.tweetText, item.getText())
                .setText(R.id.tweetDate, item.getCreatedAt())
                .setImageUrl(R.id.tweetAvatar, item.getUserAvatar())
                .setVisible(R.id.tweetRT, item.isRetweet())
                .linkify(R.id.tweetText);
    }
}

优化前和优化后的代码量是3:1的比例!

我的天啦!太不可思议了!

现在来分析,如何优化的?(带着问题学习)
思路:
找到重复部分代码,抽取到基类,非重复部分用抽象方法代替,具体让子类实现。
说了思路在看看具体代码BaseQuickAdapter里面怎么写的:

@Override
public int getItemCount() {
    return data.size();
}
@Override
public BaseAdapterHelper onCreateViewHolder(ViewGroup parent, int viewType) {
    View item = LayoutInflater.from(parent.getContext()).inflate(layoutResId, parent, false);
    return new BaseViewHolder(context, item);
}
@Override
public void onBindViewHolder(BaseViewHolder holder, final int position) {
    convert(holder, data.get(position));
}
protected abstract void convert(BaseViewHolder helper, T item);

接下来再看看BaseViewHolder怎么写的:

public class BaseViewHolder extends RecyclerView.ViewHolder {
    private final SparseArray views;
    private final Context context;
    private View convertView;

    protected BaseViewHolder(Context context, View view) {
        super(view);
        this.context = context;
        this.views = new SparseArray();
        convertView = view;
    }
    protected  T retrieveView(int viewId) {
        View view = views.get(viewId);
        if (view == null) {
            view = convertView.findViewById(viewId);
            views.put(viewId, view);
        }
        return (T) view;
    }
    public BaseViewHolder setText(int viewId, CharSequence value) {
        TextView view = retrieveView(viewId);
        view.setText(value);
        return this;
    }
    public BaseViewHolder setImageUrl(int viewId, String imageUrl) {
        ImageView view = retrieveView(viewId);
        Picasso.with(context).load(imageUrl).into(view);
        return this;
    }
    public BaseViewHolder setVisible(int viewId, boolean visible) {
        View view = retrieveView(viewId);
        view.setVisibility(visible ? View.VISIBLE : View.GONE);
        return this;
    }
    public BaseViewHolder linkify(int viewId) {
        TextView view = retrieveView(viewId);
        Linkify.addLinks(view, Linkify.ALL);
        return this;
    }
    //此处省略若干常用赋值常用方法
}

利用SparseArray来做缓存,把常用方法全部写好,从而避免冗余代码。


扩展功能

大家都知道RecyclerView没有ItemClick方法,可以在上面提过的BaseQuickAdapter里面添加ItemClick,可以这样:

网上有很多写法都是在onBindViewHolder里面写,功能是可以实现但是会导致频繁创建,应该在 onCreateViewHolder() 中每次为新建的 View 设置一次就行了。

private OnRecyclerViewItemClickListener onRecyclerViewItemClickListener;

public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener onRecyclerViewItemClickListener) {
    this.onRecyclerViewItemClickListener = onRecyclerViewItemClickListener;
}

public interface OnRecyclerViewItemClickListener {
    public void onItemClick(View view, int position);
}

@Override
public void onCreateViewHolder(ViewGroup parent, int viewType) {
    // init ViewHolder ...
    if (onRecyclerViewItemClickListener != null) {
        holder.getView().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onRecyclerViewItemClickListener.onItemClick(v, holder.getLayoutPosition());
            }
        });
    }
}

还可以添加一些常用的方法如:

public void remove(int position) {
    data.remove(position);
    notifyItemRemoved(position);
}
public void add(int position, T item) {
    data.add(position, item);
    notifyItemInserted(position);
}

代码我已经上传到GitHub上了,有兴趣的同学Star或者一起共同将它完成的更完善!送大家一句我非常喜欢的话:不分享谁与你共享呢?

源码地址:传送门

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/12889.html

相关文章

  • RecycleView相关

    摘要:接下来通过一系列的文章讲解如何使用处理常见的的一些问题自定义实现下拉刷新,加载更多自定义实现下拉刷新,加载更多增强版之继承自,堪称增强版。自我感觉本系列算是中文关于资料中的干货。因网上有大量半吊子写的相关的中文文章。 Android ItemTouchHelper 实践 实现 RecyclerView 拖动排序和滑动删除,我想到的是 ViewDragHelper ,或者是第三方库,当我...

    weij 评论0 收藏0
  • RecyclerView封装库和综合案例【包含25篇博客】

    摘要:支持复杂页面,例如添加自定义头部和底部布局,支持横向滑动,还可以支持粘贴头部类似微信好友分组,支持不规则瀑布流效果,支持侧滑删除功能。支持粘贴头部的需求效果,这种效果类似微信好友分组的那种功能界面。 目录介绍 1.复杂页面库介绍 2.本库优势亮点 2.1 支持多种状态切换管理 2.2 支持添加多个header和footer 2.3 支持侧滑功能和拖拽移动 2.4 其他亮点介绍 ...

    silenceboy 评论0 收藏0
  • RecyclerView瀑布流优化方案探讨

    摘要:是规则的瀑布流。普通的尺寸会出现错位的问题索引这个是右边这个是左边间距解决办法,可以通过里的来判断,这个方法不管你高度怎样,他都是左右左右开始排列的。 目录介绍 01.规则瀑布流实现02.不规则瀑布流实现2.1 实现方式2.2 遇到问题03.瀑布流上拉加载04.给瀑布流设置分割线05.自定义Manager崩溃06.如何避免刷新抖动07.为何有时出现跳动08.瀑布流图片优化09.onBi...

    zhaofeihao 评论0 收藏0
  • BaseRecyclerViewAdapterHelper

    摘要:作为最常用的控件,受益群体几乎是所有开发者,希望更多开发者能够一起来维护这个项目,把这个项目做得更好,帮助更多人。我的项目可加群,申请的时候把的账号名字备注上否则不予通过,谢谢配合。 RecyclerView作为Android最常用的控件,受益群体几乎是所有Android开发者,希望更多开发者能够一起来维护这个项目,把这个项目做得更好,帮助更多人。Star我的项目可加Q群5581787...

    tommego 评论0 收藏0
  • RecyclerView问题汇总

    摘要:缺点自动装箱的存在意味着每一次插入都会有额外的对象创建。对象本身是一层额外需要被创建以及被垃圾回收的对象。相较于我们舍弃了和类型的放弃了并依赖于二分法查找。 目录介绍 25.0.0.0 请说一下RecyclerView?adapter的作用是什么,几个方法是做什么用的?如何理解adapter订阅者模式? 25.0.0.1 ViewHolder的作用是什么?如何理解ViewHolder...

    boredream 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<