啥是RecyclerView
A flexible view for providing a limited window into a large data set.
一个在大小有限的窗口内展示大量数据集的view。恩,我的翻译一向不咋滴。。所以原文也放上了。
RecyclerView网上很多文都说是用来取代ListView和GridView的,事实上RecyclerView的确可以做到ListView和GridView能做的事,而且他将ViewHolder和Adapter都作为内部类,写在了RecyclerView中。先不管这把所有类都写在RecyclerView内部的做法是否好,但是ViewHolder作为RecyclerView内部复用的单位,直接避免了不必要的findViewById,而在ListView中则需要我们自己定义ViewHolder。
一个使用RecyclerView的示例
在进行探究之前,首先回顾一下我们是如何使用一个RecyclerView的。
第一步在布局文件里加上RecyclerView:
第二步,给RecyclerView的item编写布局:
第三步,为RecyclerView写一个Adapter:
packagecom.xiasuhuei321.test;importandroid.content.Context;importandroid.support.v7.widget.RecyclerView;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.view.ViewGroup;importandroid.support.v7.widget.RecyclerView.ViewHolder;/**
* Created by xiasuhuei321 on 2016/12/25.
* author:luo
* e-mail:xiasuhuei321@163.com
*/publicclassTestAdapterextendsRecyclerView.Adapter{ContextmContext;publicTestAdapter(Contextcontext){this.mContext=context;}@OverridepublicViewHolderonCreateViewHolder(ViewGroupparent,intviewType){returnnewItemViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_test,parent,false));}@OverridepublicintgetItemCount(){return100;}@OverridepublicvoidonBindViewHolder(ViewHolderholder,intposition){}classItemViewHolderextendsViewHolder{publicItemViewHolder(ViewitemView){super(itemView);}}}
这里只是简单的演示,代码写的都非常的简单。。各位都不要模仿。。。
第四步,给RecyclerView设置对应的布局和Adapter:
packagecom.xiasuhuei321.test;importandroid.os.Bundle;importandroid.support.annotation.Nullable;importandroid.support.v7.app.AppCompatActivity;importandroid.support.v7.widget.LinearLayoutManager;importandroid.support.v7.widget.RecyclerView;/**
* Created by xiasuhuei321 on 2016/12/25.
* author:luo
* e-mail:xiasuhuei321@163.com
*/publicclassTestActivityextendsAppCompatActivity{privateRecyclerViewmList;@OverrideprotectedvoidonCreate(@NullableBundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);mList=(RecyclerView)findViewById(R.id.rv_list);mList.setLayoutManager(newLinearLayoutManager(this));mList.setAdapter(newTestAdapter(this));}}
最后看下效果
呆毛王
通过以上的流程,对RecyclerView的简单使用就过完了,在这个流程中,可以看出编写Adapter是一个关键,事实上RecyclerView和ListView都一样,都是通过Adapter来设置和管理每一个item的。
ViewHolder与复用
在复写RecyclerView.Adapter的时候,需要我们复写两个方法:
onCreateViewHolder
onBindViewHolder
这两个方法从字面上看就是创建ViewHolder和绑定ViewHolder的意思,来看一下源码中对我们实现的这两个方法的注释:
/**
* Called when RecyclerView needs a new {@link ViewHolder} of the given type to represent
* an item.
*
* This new ViewHolder should be constructed with a new View that can represent the items
* of the given type. You can either create a new View manually or inflate it from an XML
* layout file.
*
* The new ViewHolder will be used to display items of the adapter using
* {@link #onBindViewHolder(ViewHolder, int, List)}. Since it will be re-used to display
* different items in the data set, it is a good idea to cache references to sub views of
* the View to avoid unnecessary {@link View#findViewById(int)} calls.
*
* @param parent The ViewGroup into which the new View will be added after it is bound to
* an adapter position.
* @param viewType The view type of the new View.
*
* @return A new ViewHolder that holds a View of the given view type.
* @see #getItemViewType(int)
* @see #onBindViewHolder(ViewHolder, int)
*/
当RecyclerView需要一个新的类型的item的ViewHolder的时候调用这个方法。
第二段描述是讲如何创建这个ViewHolder,跳过。
新的ViewHolder将会被用来通过adapter调用onBindViewHolder展示item。由于它将会被复用去展示在数据集中的不同items,所以缓存View的子view引用去避免不必要的对findViewById方法的调用是一个好主意。
看了上面的这段话,我产生了一个疑问,第一段话的意思仿佛是只有在需要新的类型的ViewHolder的时候才需要调用这个方法。如果是这样,的确可以从侧面说明他是以ViewHolder为单位来实现复用的。为了验