RecyclerView经验

来源:互联网 发布:写一个数组去重 编辑:程序博客网 时间:2024/06/04 18:13
last update date 2016/11/01 github demo

与ListView对比

Recyclerview可以看做是新时代的ListView,对ListView的扩充,是时代潮流.主要表现在:缓存更强大.支持局部更新.方便的动画设置以及默认动画.能与其他新的API配合(Material Design 风格).
缓存的对比可以参考这篇文章:Android ListView 与 RecyclerView 对比浅析–缓存机制
看上面文章的时候已经把ListView优化原理忘了,毕竟很久没用了,所以重新回顾了一遍.
实际应用中我们要做的第一个优化点是重复利用废弃的contentView,在getView中,有参数contentView,这个就是listView会缓存的废弃的View.第一次加载布局项(contentView为空),Inflater拿到布局view.之后直接使用缓存的contentview,这个时候contentView不为空.避免多次inflater.
第二个是将一个Holder当作tag设置到contentView,contentView不为空通过getTag()拿到Holder直接使用,避免重复的findViewById.
@Override
public View getView( int position, View convertView, ViewGroup parent) {
Holder holder=null;
final ChatMsg msg=mChatMsgList.get(position);
if(convertView==null){
convertView=getLayoutInflater().inflate(R.layout.chatting_item_left, parent, false);
holder=new Holder();
holder.textView=(TextView) convertView.findViewById(R.id.message);
holder.imageView=(ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
}else {
holder=(Holder) convertView.getTag();
}
holder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showToast(msg.msg);
}
});
holder.textView.setText(msg.msg);
return convertView;
}

看别人的文章分析ListView自身对view的绘制,适配与缓存做了很多功夫,有兴趣可以去看看.
而RecyclerView没有让我们关心这些事情,使用了它这么久,该花时间去了解它的神奇.同时也思考下为什么RecyclerView能够扩充ListView架构做不到的事情.上边的文章有关于RecyView的分析,我会基于它再结合其他的资料写下我的体会.

快速新建

  1. RecyclerView滚动条设置:android:scrollbars=”vertical/none/horizontal”,代码可以设置滚动条的大小,style.
  2. Adapter继承RecyclerView.Adapter.
    1. 先写构造函数,一般是data赋值(data直接=引用,方便快捷)与回调接口设置,所以创建内部public接口CallBack,添加回调方法,如:itemOnclick().
    2. 然后item布局.创建私有内部类ViewHolder继承RecyclerView.ViewHolder.ViewHolder构造方法(快速生成),super方法写在第一行.写类全局变量(view),构造方法中findViewById给全局变量赋值.
    3. 写onCreateViewHolder,return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_int_list, parent, false))
    4. getItemCount()与 getItemViewType(int position)
    5. onBindViewHolder(),根据需要getItemView强转成自己写的内部类ViewHolder,给view设置动态数据.
      View的事件监听建议在这里设置.
  3. 设置LayoutManager,Adapter.
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
    mRecyclerView.setAdapter(mAdapter);

抽取基类

基类减少重复公共代码,封装复杂实现对外提供简单方便调用方法.具体见demo的BasicRecyclerView
1. 设置默认的LayoutManger
2. 提供简单设置分割线的系列方法setDivider()
3. 提供简单设置动画效果方法()//todo

注意点

  1. onBindViewHolder(RecyclerView.ViewHolder holder, int position, List payloads)
    payload用于item notify的时候只更新局部的view,例如一个选择框,而不是整个view
    如:
    @Override
    public void onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) {
    if (payloads.isEmpty()) {
    // payloads 为 空,说明是更新整个 ViewHolder
    onBindViewHolder(holder, position);
    } else {
    // payloads 不为空,这只更新需要更新的 View 即可。
    holder.mBadgeView.setVisibility(((Item)payloads.get(0)).disabled ? View.VISIBLE : View.INVISIBLE);
    }
    }

    使用 Payload 提高 RecyclerView 渲染效率
  2. 列表项位置问题.当监听事件的形参是位置的时候:
      如果传position,这个position是bind时在数据集中的位置,是不会变动.即使列表有变动,这个值也是不会变的.
      
      如果传vh.getAdapterPosiiton()表示是当前适配器中的位置.常见的删除操作, 传这个.大部分情况getLayoutPosition与getAdapterPosition的值是一致的.更新列表的操作使用AdapterPosition较好,因为最终的LayoutPosition会与AdapterPosition一致.有些情况下会返回-1,所以有做安全判断,AdapterPosition>=0.
      
      两者的区别http://stackoverflow.com/questions/29684154/recyclerview-viewholder-getlayoutposition-vs-getadapterposition.源码的注释也有描述,但stackover的易理解.
  3. 选择框(单多全正反选)
      

使用DiffUtil高效更新RecyclerView

Support Library 24.2.0提供了一个类DiffUtil,看源码

下拉刷新与上拉加载更多

字母导航栏

item侧滑

0 0
原创粉丝点击