RecycleView的基本使用方法

来源:互联网 发布:彩卡网络下单系统 编辑:程序博客网 时间:2024/05/17 22:57

为什么要使用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> {

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

@Overridepublic 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;         ...      }  }@Overridepublic 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的基本使用就可是这样了。

2 0
原创粉丝点击