博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RecyclerView.Adapter优化了吗?
阅读量:6331 次
发布时间:2019-06-22

本文共 5758 字,大约阅读时间需要 19 分钟。

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

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

  • 精简代码

  • 扩展功能


列表.png

精简代码

正常没优化的写法:

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里面怎么写的:

@Overridepublic int getItemCount() {    return data.size();}@Overridepublic BaseAdapterHelper onCreateViewHolder(ViewGroup parent, int viewType) {    View item = LayoutInflater.from(parent.getContext()).inflate(layoutResId, parent, false);    return new BaseViewHolder(context, item);}@Overridepublic 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);}@Overridepublic 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或者一起共同将它完成的更完善!送大家一句我非常喜欢的话:不分享谁与你共享呢?

源码地址:

转载地址:http://kjboa.baihongyu.com/

你可能感兴趣的文章
Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析(2)
查看>>
Lync 小技巧-5-当前已暂停共享
查看>>
无线802.11n 2.4G与5G性能测试
查看>>
子域名信息收集攻略
查看>>
[Android]开发数独游戏思路分析过程
查看>>
SpreadJS 类Excel表格控件 - V12 新特性详解
查看>>
理解并取证:IPv6与IPv4在报文结构上的区别
查看>>
EOS主网上线只是开始,如何运营决定未来
查看>>
不用Visual Studio,5分钟轻松实现一张报表
查看>>
(译)如何使用cocos2d和box2d来制作一个Breakout游戏:第一部分
查看>>
计算机图形学(一) 图形系统综述
查看>>
持续集成(CI)- 几种测试的区别(摘录)
查看>>
多用户虚拟Web3D环境Deep MatrixIP9 1.04发布
查看>>
求高手,求解释
查看>>
[MSSQL]NTILE另类分页有么有?!
查看>>
winform datagridview 通过弹出小窗口来隐藏列 和冻结窗口
查看>>
Jquery闪烁提示特效
查看>>
最佳6款用于移动网站开发的 jQuery 图片滑块插件
查看>>
C++ String
查看>>
获取系统托盘图标的坐标及文本
查看>>