什麼是RecyclerView
RecyclerView是Android 5.0 materials design中的組件之一,相應的還有CardView、Palette等。看名字我們就能看出一點端倪,沒錯,它主要的特點就是複用。我們知道,Listview中的Adapter中可以實現ViewHolder的複用。RecyclerView提供了一個耦合度更低的方式來複用ViewHolder,並且可以輕鬆的實現ListView、GridView以及瀑布流的效果。
幾個重要的類
1、RecyclerView.Adapter:抽象類,爲RecyclerView提供數據,一般根據不同的業務需求來編寫具體的實現類。
2、RecyclerView.LayoutManager:抽象類,主要用於測量RecyclerView的子Item,以及根據不同的佈局方式來實現Item的佈局效果,v 7包自帶的實現類有:LinearLayoutManager、StaggeredGridLayoutManager、GridLayoutManager。
3、RecyclerView.ItemDecoration:抽象類,這個主要用於不同的Item之間添加分割線(可選)。官方沒有實現類,所以如果要添加分割線,我們需要手動實現這個抽象類。
4、RecyclerView.ItemAnimator:抽象類,這個主要用於當一個item添加或者刪除的時候出現的動畫效果,官方提供一個默認的實現類。如果想要使我們的RecyclerView在添加、刪除數據的時候有炫酷的動畫,可以實現這個抽象類。
可以看到,這些重要的類都是抽象類,這就爲RecyclerView的高度可定製性打下了堅實的基礎,利用不同的實現類,能自由、靈活地使用RecyclerView,這也是RecyclerView的迷人之處。
簡單使用步驟
添加依賴
compile 'com.android.support:recyclerview-v7:24.2.1'
佈局
<android.support.v7.widget.RecyclerView
android:id="@+id/fragment_recycle_recycleview_ry"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
使用
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));//設置爲線性LayoutManager
//在這裏通過換LayoutManager這個設置能實現listview,gridview,瀑布流等不同效果
recyclerView.setAdapter(adapter);//添加適配器
adapter.setmDatas(mDatas);//適配器添加數據
adapter.notifyDataSetChanged();//刷新
創建適配器
RecyclerView需要適配器來提供數據。上面說到RecyclerView提供了一個抽象類:RecyclerView.Adapter,我們通過繼承該類來寫自己的適配器。我們先看看這個抽象類裏面的抽象方法:
public static abstract class Adapter {
public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);
public abstract void onBindViewHolder(VH holder, int position);
public abstract int getItemCount();
}
繼承該類的時候,必須重寫這三個方法,我們分別解釋一下這三個方法是什麼作用:
①onCreateViewHolder:創建ViewHolder,該方法會在RecyclerView需要展示一個item的時候回調。重寫該方法時,應該使ViewHolder加載item view的佈局。這個能發避免了不必要的findViewById操作,提高了性能。如果熟悉ListView的ViewHolder操作那麼也能很容易理解這個。
②onBindeViewHolder:該方法在RecyclerView在特定位置展示數據時候回調,顧名思義,把數據綁定、填充到相應的item view中。
③getItemCount:返回數據的數量。
我們注意到,繼承該類的時候需要聲明它的泛型類型VH,VH繼承自RecyclerView.ViewHolder,同時第①個方法的返回值也是VH,由於ViewHolder是根據業務需求而變化的,不同的業務需求而需要的ViewHolder不盡相同,所以沒必要單獨寫一個ViewHolder.Java文件,因此我們可以在Adapter子類內部實現一個內部類ViewHolder,這樣也符合單一職責原則。
public class LinearAdapter3 extends RecyclerView.Adapter<LinearAdapter3.MyViewHolder> {
private Context context;
private List<String> mDatas;
public LinearAdapter3(Context context){
this.context=context;
}
public List<String> getmDatas() {
return mDatas;
}
public void setmDatas(List<String> mDatas) {
this.mDatas = mDatas;
}
//創建viewholder
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v= LayoutInflater.from(
context).inflate(R.layout.item_home, parent,
false);
LinearAdapter3.MyViewHolder holder = new LinearAdapter3.MyViewHolder(v);
return holder;
}
//綁定數據
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tv.setText(mDatas.get(position));
holder.itemView.setTag(mDatas.get(position));
}
//有多少條
@Override
public int getItemCount() {
return mDatas.size();
}
//viewholder 內部類
static class MyViewHolder extends RecyclerView.ViewHolder
{
TextView tv;
public MyViewHolder(View view)
{
super(view);
tv = (TextView) view.findViewById(R.id.id_num);
}
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#FFE4C4"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/id_num"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:text="1" />
</FrameLayout>