如何使用RecyclerView?

這篇文章是根據官網的一篇文章(這裏)寫的,不過作者增加了一些自己的理解,我十分推崇這種方式,而不是死板的翻譯官網的文檔,國內技術文章翻譯的最差的地方在於:翻譯出來的句子還保留着英語的語序。

RecyclerView 是Android L版本中新添加的一個用來取代ListView的SDK,它的靈活性與可替代性比listview更好。接下來通過一系列的文章講解如何使用RecyclerView,徹底拋棄ListView.

介紹

RecyclerView與ListView原理是類似的:都是僅僅維護少量的View並且可以展示大量的數據集。RecyclerView用以下兩種方式簡化了數據的展示和處理:

  • 使用LayoutManager來確定每一個item的排列方式。

  • 爲增加和刪除項目提供默認的動畫效果。

你也可以定義你自己的LayoutManager和添加刪除動畫,RecyclerView項目結構如下:

  • Adapter:使用RecyclerView之前,你需要一個繼承自RecyclerView.Adapter的適配器,作用是將數據與每一個item的界面進行綁定。

  • LayoutManager:用來確定每一個item如何進行排列擺放,何時展示和隱藏。回收或重用一個View的時候,LayoutManager會向適配器請求新的數據來替換舊的數據,這種機制避免了創建過多的View和頻繁的調用findViewById方法(與ListView原理類似)。

目前SDK中提供了三種自帶的LayoutManager:

  • LinearLayoutManager

  • GridLayoutManager

  • StaggeredGridLayoutManager

第一節、簡單的RecyclerView使用方法

本節所示示例是一個最簡單的使用方法,在接下來幾節中將會介紹更多RecyclerView的別的一些屌爆的用法。作者用的環境是Android Studio 0.8.6。

1、添加依賴

在AS的build.gradle中添加依賴,然後同步一下就可以引入依賴包:

1
2
3
4
dependencies {
...
compile 'com.android.support:recyclerview-v7:21.0.+'
}

2、編寫代碼

添加完依賴之後,就開始寫代碼了,與ListView用法類似,也是先在xml佈局文件中創建一個RecyclerView的佈局:

1
2
3
4
5
6
7
8
9
10
11
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"/>
</RelativeLayout>

創建完佈局之後在MainActivity中獲取這個RecyclerView,並聲明LayoutManagerAdapter,代碼如下:

1
2
3
4
5
6
7
8
9
mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
//創建默認的線性LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//如果可以確定每個item的高度是固定的,設置這個選項可以提高性能
mRecyclerView.setHasFixedSize(true);
//創建並設置Adapter
mAdapter = newMyAdapter(getDummyDatas());
mRecyclerView.setAdapter(mAdapter);

接下來的問題就是Adapter的創建:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    public String[] datas = null;
    public MyAdapter(String[] datas) {
        this.datas = datas;
    }
    //創建新View,被LayoutManager所調用
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item,viewGroup,false);
        ViewHolder vh = new ViewHolder(view);
        return vh;
    }
    //將數據與界面進行綁定的操作
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {
        viewHolder.mTextView.setText(datas[position]);
    }
    //獲取數據的數量
    @Override
    public int getItemCount() {
        return datas.length;
    }
    //自定義的ViewHolder,持有每個Item的的所有界面元素
    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView mTextView;
        public ViewHolder(View view){
        super(view);
            mTextView = (TextView) view.findViewById(R.id.text);
        }
    }
}

3、運行

寫完這些代碼這個例子既可以跑起來了。從例子也可以看出來,RecyclerView的用法並不比ListView複雜,反而更靈活好用,它將數據、排列方式、數據的展示方式都分割開來,因此可定製型,自定義的形式也非常多,非常靈活。

橫向佈局

如果想要一個橫向的List只要設置LinearLayoutManager如下就行,注意要聲明mLayoutManager的類型是LinearLayoutManager而不是父類LayoutManager:

1
mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

Grid佈局

如果想要一個Grid佈局的列表,只要聲明LayoutManager爲GridLayoutManager即可:

1
2
mLayoutManager = new GridLayoutManager(context,columNum);
mRecyclerView.setLayoutManager(mLayoutManager);

注意,在Grid佈局中也可以設置列表的Orientation屬性,來實現橫向和縱向的Grid佈局。

瀑布流佈局

瀑布流就使用StaggeredGridLayoutManager吧,具體方法與上面類似,就不做介紹啦。

總結

本節介紹的是一個最最簡單的RecyclerView的使用方法,後面將介紹一些更高級的用法。




第二節、RecyclerView的高級方法


當使用了一段時間的RecyclerView,發現爲其每一項添加點擊事件並沒有ListView那麼輕鬆,像ListView直接加個OnItemClickListener就行了。實際上我們不要把RecyclerView當做ListView的一個升級版,希望大家把他看做一個容器,同時裏面包含了很多不同的Item,它們可以以不同方式排列組合,非常靈活,點擊方式你可以按照你自己的意願進行實現。

本節主要講解如何爲RecyclerView添加點擊事件, 並簡單介紹如何進行Item增加刪除。

添加點擊事件

上一節中我們講了如何使用RecyclerView的Adpater,其實我們會發現,Adapter是添加點擊事件一個很好的地方,裏面是構造佈局等View的主要場所,也是數據和佈局進行綁定的地方。首先我們在Adapter中創建一個實現點擊接口,其中view是點擊的Item,data是我們的數據,因爲我們想知道我點擊的區域部分的數據是什麼,以便我下一步進行操作:

1
2
3
public static interface OnRecyclerViewItemClickListener {
    void onItemClick(View view , DataModel data);
}

定義完接口,添加接口和設置Adapter接口的方法:

1
2
3
4
private OnRecyclerViewItemClickListener mOnItemClickListener = null;
    public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {
    this.mOnItemClickListener = listener;
}

那麼這個接口用在什麼地方呢?如下代碼所示,我們爲Adapter實現OnClickListener方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener{
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, final int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        ViewHolder vh = new ViewHolder(view);
        //將創建的View註冊點擊事件
        view.setOnClickListener(this);
        return vh;
    }
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int i) {
        viewHolder.mTextView.setText(datas.get(i).title);
        //將數據保存在itemView的Tag中,以便點擊時進行獲取
        viewHolder.itemView.setTag(datas.get(i));
    }
    ...
    @Override
    public void onClick(View v) {
        if (mOnItemClickListener != null) {
            //注意這裏使用getTag方法獲取數據
            mOnItemClickListener.onItemClick(v,(DataModel)v.getTag());
        }
    }
    ...
}

做完這些事情,我們就可以在Activity或其他地方爲RecyclerView添加項目點擊事件了,如在MainActivity中:

1
2
3
4
5
6
7
8
mAdapter = new MyAdapter(getDummyDatas());
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new MyAdapter.OnRecyclerViewItemClickListener() {
    @Override
    public void onItemClick(View view, DataModel data) {
        //DO your fucking bussiness here!
    }
});

完成了以上代碼就可以爲RecyclerView添加項目點擊事件了,下面我們來看看RecyclerView如何添加和刪除數據並在界面上顯示。

添加刪除數據

以前在ListView當中,我們只要修改後數據用Adapter的notifyDatasetChange一下就可以更新界面。然而在RecyclerView中還有一些更高級的用法:

添加數據:

1
2
3
4
public void addItem(DataModel content, int position) {
    datas.add(position, content);
    notifyItemInserted(position); //Attention!
}

刪除數據:

1
2
3
4
5
public void removeItem(DataModel model) {
    int position = datas.indexOf(model);
    datas.remove(position);
    notifyItemRemoved(position);//Attention!
}

值得注意的是RecyclerView的添加刪除都是有默認的動畫效果的,如果沒有效果可以添加如下代碼:

1
mRecyclerView.setItemAnimator(newDefaultItemAnimator());

當然啦你也可以自己定義你自己的Animator,等我研究明白了也來講一講如何自定義這些效果~


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