RecyclerView的詳細使用

谷歌在support v7中,加入了新的控件——RecyclerView,該控件整合了ListView、GridView的特點,而且最大的優點是可以很方便實現瀑布流效果,因此RecyclerView受到越來越多的開發者重視。所以,學習RecyclerView的使用也是很有必要的。

 

引入RecyclerView

由於該控件並不在Andorid SDK中的,而是在support v7包中,因此我們要手動添加該控件。
在build.gradle中添加如下依賴:

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


 

幾個重要的類

在認識RecyclerView的用法之前,我們要先認識幾個它常用的內部類,因爲這幾個內部類很重要,貫穿整個使用過程:
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的優秀之處。

開始上代碼

 

一、recyclerView的佈局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.recyclerview.MainActivity">

   <android.support.v7.widget.RecyclerView
       android:id="@+id/recyclerView"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"/>
</RelativeLayout>


二、MainActivity中的代碼

 

public class MainActivity extends AppCompatActivity {

    private Toolbar toolbar;
    private RecyclerView mRecyclerView;
    private RecyclerView.LayoutManager mLayoutManager;
    private MyAdapter mAdapter;
    private List<String> mData;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initToolbar();
        initData();
        initRecyclerView();
    }

    private void initData() {
        mData = new ArrayList<>();
        for(int i=0;i<20;i++){
            mData.add("Item "+i);
        }
    }

    private void initRecyclerView() {
        //1 實例化RecyclerView
        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        mLayoutManager = new LinearLayoutManager(this);
        //2 爲RecyclerView創建佈局管理器,這裏使用的是LinearLayoutManager,表示裏面的Item排列是線性排列
        mRecyclerView.setLayoutManager(mLayoutManager);
        mAdapter = new MyAdapter(mData);
        //3 設置數據適配器
        mRecyclerView.setAdapter(mAdapter);
    }


三、最重要的適配器的Adapter的代碼

與ListView類似地,RecyclerView也需要適配器來提供數據。上面說到RecyclerView提供了一個抽象類:RecyclerView.Adapter,我們通過繼承該類來寫自己的適配器。

public static abstract class Adapter<VH extends ViewHolder> {
    public abstract VH onCreateViewHolder(ViewGroup parent, int viewType); // 1
    public abstract void onBindViewHolder(VH holder, int position); // 2
    public abstract int getItemCount(); // 3
}

繼承該類的時候,必須重寫這三個方法,我們分別解釋一下這三個方法是什麼作用:
①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,這樣也符合單一職責原則。具體的Adapter適配器代碼如下所示,MyAdapter.java:

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

    private List<String> mDataSet;

    //構造器,接受數據集
    public MyAdapter(List<String> data){
        mDataSet = data;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //加載佈局文件
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemlayout,parent,false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        //將數據填充到具體的view中
        holder.mTextView.setText(mDataSet.get(position));
    }

    @Override
    public int getItemCount() {
        return mDataSet.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder{
        public TextView mTextView;
        public ViewHolder(View itemView) {
            super(itemView);
            //由於itemView是item的佈局文件,我們需要的是裏面的textView,因此利用itemView.findViewById獲      
            //取裏面的textView實例,後面通過onBindViewHolder方法能直接填充數據到每一個textView了
            mTextView = (TextView) itemView.findViewById(R.id.num);
        }
    }
}

 

以上的代碼的執行結果大概是這樣

 


 

 


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章