RecycleView的基本使用方法

为什么要使用RecycleView,而不再使用ListView

记得每一次在用ListView的时候,在Adapter中,总是需要我们自己去创建一个ViewHolder,去存储ListItem的布局,这么做的原因在于findViewById()是一个很耗时间的操作,所以我们需要一个静态的对象将layout过的控件给保存起来,下一次刷新这个item的时候,就不再需要调用findViewById去ViewTree中初始化控制,从而达到对ListView的优化效果。

而RecycleView则已经帮我们封闭好了这样一个ViewHolder的抽象类RecycleView.ViewHolder,而且是必须实现的一个接口,这说明在控制节省内存方面,RecycleView要比ListView做得要好,因为在ListView中,你不写ViewHolder也是可以的。

此外,ListView的设计是一个上下滑动的列表控制,而RecycleView则通过一个LayoutManager来实现多种布局的展现,包括纵向列表,横向Gallery,Grid布局,基于瀑布流等,可以说,之前通过ListView, GridView, ViewPager等实现的布局,现在用一个RecycleView就可以实现了。

再此外,现在的很多app,就算是使用ListView,也不仅仅是单纯地展现数据,都希望能够利用一些平滑的动画效果来提升用户体验,而RecycleView本身在对数据的增删上就添加了对动画的效果的的支持。
在RecyclerView中增加了以下的接口:

        public final void notifyItemInserted(int position) {
            mObservable.notifyItemRangeInserted(position, 1);
        }
        public final void notifyItemMoved(int fromPosition, int toPosition) {
            mObservable.notifyItemMoved(fromPosition, toPosition);
        }  

    public void setItemAnimator(ItemAnimator animator) {
        if (mItemAnimator != null) {
            mItemAnimator.endAnimations();
            mItemAnimator.setListener(null);
        }
        mItemAnimator = animator;
        if (mItemAnimator != null) {
            mItemAnimator.setListener(mItemAnimatorListener);
        }
    }       

综合种种,个人觉得,是很有必要掌握一下如何使用RecycleView的。

如何使用 RecycleView

RecycleView是Support-v7包中的组件,因此在Gradle中,我们要添加其对应的引用

dependencies {
    ...
    compile 'com.android.support:recyclerview-v7:23.1.0'
    ...
}

在xml布局中,如下使用

    <android.support.v4.widget.SwipeRefreshLayout  android:id="@+id/swipe_refresh_widget" android:layout_width="match_parent" android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView  android:id="@+id/order_list" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="@dimen/normal_space" />
    </android.support.v4.widget.SwipeRefreshLayout>

在Activity中,

    private RecyclerView mOrderListView;
    private LinearLayoutManager mLayoutManager;
    private OrderListRecycleViewAdapter mOrderListAdapter;

    mOrderListView = (RecyclerView) findViewById(R.id.order_list);
    mLayoutManager = new LinearLayoutManager(this);
    mOrderListView.setHasFixedSize(true);
    mOrderListView.setLayoutManager(mLayoutManager);
    mOrderListAdapter = new OrderListRecycleViewAdapter(this, mOrderList, this);
    mOrderListView.setAdapter(mOrderListAdapter);

这里可看到分为几步:

  • 声明LayoutManager,并调用RecycleView的setLayoutManager方法进行赋值

目前SDK中提供了三种LayoutManager,分别为

  • LinearLayoutManager
  • GridLayoutManager
  • StaggeredGridLayoutManager

使用不同的LayoutManager,分别如下:

  • 使用LinearLayoutManager
mLayoutManager = new LinearLayoutManager(this)
  • 使用GridLayoutManager
mLayoutManager = new GridLayoutManager(this, 1, LinearLayoutManager.Vertical, false)

GridLayoutManager的构造有如下几种:

    /** * Creates a vertical GridLayoutManager * * @param context Current context, will be used to access resources. * @param spanCount The number of columns in the grid */
    public GridLayoutManager(Context context, int spanCount) {
        super(context);
        setSpanCount(spanCount);
    }

    /** * @param context Current context, will be used to access resources. * @param spanCount The number of columns or rows in the grid * @param orientation Layout orientation. Should be {@link #HORIZONTAL} or {@link * #VERTICAL}. * @param reverseLayout When set to true, layouts from end to start. */
    public GridLayoutManager(Context context, int spanCount, int orientation,
            boolean reverseLayout) {
        super(context, orientation, reverseLayout);
        setSpanCount(spanCount);
    }

在这里,按照我们上述的声明,其实现的效果跟LinearLayout的效果是一致的,当SpanCount值大于1的时候,就能够以格式的效果展现,这种切换其实还是挺简单的,是不?

  • StaggeredGridLayoutManager
StaggeredGridLayoutManager mLayoutManager = new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL);

看效果就已经能够实现简单的瀑布流了。

接下来还要对recycleView设置以下的方法:

  1. 设置hasFixedSize方法
    调用此方法,可让RecycleView保持展现的item数目,在RecycleView的实现中会有一些优化。

  2. 声明Adapter,将调用RecycleView的setAdapter方法进行赋值。

到这里,除了去实现 Adapter之后,对RecycleView的初始化及使用,到此即可。

除此之外,我们还能够调用RecycleView的addItemDecoration方法和setItemAnimator方法来自定义item的分隔线及item的动画效果。

mOrderListView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));

mOrderListView.setItemAnimator(new DefaultItemAnimator());

实现Adapter

我们实现的Adapter必须继承于RecycleView.Adapter,如下

public class OrderListRecycleViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

而需要我们去实现的方法,如下展示:


@Override
public int getItemViewType(int position) {
    if (position + 1 == getItemCount()) {
        return TYPE_FOOTER;
    } else {
        return TYPE_ITEM;
    }
}

@Override
 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
     if (TYPE_ITEM == viewType) {
         View view = LayoutInflater.from(mContext).inflate(R.layout.order_list_item, parent, false);
         return new OrderListViewHolder(view);
     } else {
         View view = LayoutInflater.from(mContext).inflate(R.layout.list_footer, parent, false);
         return new OrderListFooterHolder(view);
     }
 }

   @Override
  public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
      if (holder instanceof OrderListViewHolder) {
          Order order = mData.get(position);
          OrderListViewHolder itemHolder = (OrderListViewHolder) holder;
          ...
      } else if (holder instanceof OrderListFooterHolder) {
          OrderListFooterHolder footerHolder = (OrderListFooterHolder) holder;
         ...
      }
  }

@Override
public int getItemCount() {
    return mData.size() + 1;
}

static class OrderListFooterHolder extends RecyclerView.ViewHolder {
    TextView itemFooter;

    public OrderListFooterHolder(View itemView) {
        super(itemView);
        itemFooter = (TextView) itemView.findViewById(R.id.item_footer);
    }
}

static class OrderListViewHolder extends RecyclerView.ViewHolder {
      ....
      public OrderListViewHolder(View itemView) {
          super(itemView);
          ...
      }
  }

在上面这个Adapter中,其实做了几件事:

  1. public int getItemViewType(int position)
    根据getItemViewType返回我们要去加载的item布局,这一个方法的实现不是必须的,在这里只是因为需要去加载两个布局,所以就定义了两个ITEM_TYPE,如果就一个布局,这方法可以不实现。

  2. public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    如果有不同的viewType,我们则必须根据不同的viewType来从不同的item布局中,利用LayoutInflater来加载,并创建对应的ViewHolder,因此在这里,我们需要实现onCreateViewHolder方法,其会返回一个RecyclerView.ViewHolder对象。

  3. static class OrderListFooterHolder extends RecyclerView.ViewHolder

  4. static class OrderListViewHolder extends RecyclerView.ViewHolder
    既然上一步返回了一个RecyclerView.ViewHolder对象,对应的,我们就要实现自己的ViewHolder,来存储对应的组件了,如上面的OrderListFootHolder和OrderListViewHolder。

  5. public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position)
    有了ViewHolder之后,接下来就是要将ViewHolder和数据给绑定到一起来,则需要去调用OnBindViewHolder方法了,其参数一个为对应的ViewHolder,一个为对应的位置,通过此位置,去数据列表中获取对应的数据。

  6. public int getItemCount()
    最后,我们还要实现getItemCount方法,告知RecycleView,此Adapter到底要处理多少个对象。

至此,对RecycleView的基本使用就可是这样了。

    原文作者:linmiansheng
    原文地址: https://blog.csdn.net/linmiansheng/article/details/50381654
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞