RecyclerView.Adapter优化了吗?
2016-04-10 15:56
316 查看
昨天写了一篇「还在用ListView?」讲的内容是RecyclerView的使用技巧以及一些常用的开源库,有朋友反馈“我已经在用recyclerview了”,那么如何让它更好用呢?此时我想到了优化RecyclerView.Adapter,因为在RecyclerView还没出来之前我就写过一篇「ListView之Adapter优化」,通过这篇文章的优化思路可以在原来的代码上修改部分代码用在优化RecyclerView.Adapter上,一如既往的好用。
本次主要讲两个方面的优化
精简代码
扩展功能
优化后,是这样的:
优化前和优化后的代码量是3:1的比例!
我的天啦!太不可思议了!
现在来分析,如何优化的?(带着问题学习)
思路:
找到重复部分代码,抽取到基类,非重复部分用抽象方法代替,具体让子类实现。
说了思路在看看具体代码BaseQuickAdapter里面怎么写的:
接下来再看看BaseViewHolder怎么写的:
利用SparseArray来做缓存,把常用方法全部写好,从而避免冗余代码。
还可以添加一些常用的方法如:
代码我已经上传到GitHub上了,有兴趣的同学Star或者一起共同将它完成的更完善!送大家一句我非常喜欢的话:不分享谁与你共享呢?
源码地址:传送门
关注微信公众号,第一时间通知!
本次主要讲两个方面的优化
精简代码
扩展功能
精简代码
正常没优化的写法:public class DefAdpater extends RecyclerView.Adapter<DefAdpater.ViewHolder> { private final List<Status> 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<Status> { 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<View> views; private final Context context; private View convertView; protected BaseViewHolder(Context context, View view) { super(view); this.context = context; this.views = new SparseArray<View>(); convertView = view; } protected <T extends View> 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,可以这样写:private OnRecyclerViewItemClickListener onRecyclerViewItemClickListener; public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener onRecyclerViewItemClickListener) { this.onRecyclerViewItemClickListener = onRecyclerViewItemClickListener; } public interface OnRecyclerViewItemClickListener { public void onItemClick(View view, int position); } @Override public void onBindViewHolder(BaseViewHolder holder, final int position) { convert(holder, data.get(position)); if (onRecyclerViewItemClickListener != null) { holder.getView().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onRecyclerViewItemClickListener.onItemClick(v, position); } }); } }
还可以添加一些常用的方法如:
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或者一起共同将它完成的更完善!送大家一句我非常喜欢的话:不分享谁与你共享呢?
源码地址:传送门
关注微信公众号,第一时间通知!
相关文章推荐
- maven+srping+springmvc+mybatis的环境搭建的每一步和代码
- 构造方法实验代码
- 可执行程序的装载
- *windows.event对象在ie与ff中的区别**
- 剑指offer系列之5:用两个栈来实现队列
- shell uniq 和sort 简单用法及实例
- Git入门
- 区间调度问题
- 冒泡排序、选择和插入排序、二分法查找
- servlet/filter/listener/interceptor区别与联系
- 华为OJ题目(二十一):输入n个整数,输出其中最小的k个
- email正则表达式 验证邮箱格式
- ASP.NET MVC4入门教程(四):添加一个模型
- 网站挂马解决方案
- RTSP协议、RTMP协议、HTTP协议的区别
- 1005. 继续(3n+1)猜想 (25)
- 在类中使用类成员函数创建线程
- window对象
- 第六周学习进度
- javascript冒泡排序小结