????? RecyclerView 是Android 新添加的一個用來取代ListView的控件,它的靈活性與可替代性比listview更好。
看一下繼承關系:
ava.lang.Object | |||
???? | android.view.View | ||
? | ???? | android.view.ViewGroup | |
? | ? | ???? | android.support.v7.widget.RecyclerView |
Known Direct Subclasses HorizontalGridView,VerticalGridView |
介紹
RecyclerView與ListView原理是類似的:都是僅僅維護少量的View并且可以展示大量的數據集。RecyclerView用以下兩種方式簡化了數據的展示和處理:
-
使用LayoutManager來確定每一個item的排列方式。
-
為增加和刪除項目提供默認的動畫效果。
你也可以定義你自己的LayoutManager和添加刪除動畫,RecyclerView項目結構如下:
-
Adapter:使用RecyclerView之前,你需要一個繼承自RecyclerView.Adapter的適配器,作用是將數據與每一個item的界面進行綁定。
-
LayoutManager:用來確定每一個item如何進行排列擺放,何時展示和隱藏。回收或重用一個View的時候,LayoutManager會向適配器請求新的數據來替換舊的數據,這種機制避免了創建過多的View和頻繁的調用findViewById方法(與ListView原理類似)。
學習原因:
那么有了ListView、GridView為什么還需要RecyclerView這樣的控件呢?整體上看RecyclerView架構,提供了一種插拔式的體驗,高度的解耦,異常的靈活,通過設置它提供的不同LayoutManager,ItemDecoration , ItemAnimator實現令人瞠目的效果。
- 你想要控制其顯示的方式,請通過布局管理器LayoutManager
- 你想要控制Item間的間隔(可繪制),請通過ItemDecoration
- 你想要控制Item增刪的動畫,請通過ItemAnimator
- 你想要控制點擊、長按事件,需要自己實現
目前SDK中提供了三種自帶的LayoutManager:
-
LinearLayoutManager
-
GridLayoutManager
-
StaggeredGridLayoutManager
第一節、簡單的RecyclerView使用方法
本節所示示例是一個最簡單的使用方法,作者用的環境是Android Studio 1.5。
1、添加依賴
在AS的build.gradle
中添加依賴,然后同步一下就可以引入依賴包:
compile 'com.android.support:recyclerview-v7:23.1.1'
注意:版本需要和其它保持一致,如其它是 23.3,這里也需要改成23.3;
2、編寫代碼
添加完依賴之后,就開始寫代碼了,與ListView用法類似,也是先在xml布局文件中創建一個RecyclerView的布局:
<?xml version="1.0" encoding="utf-8"?> <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="com.jcdh.jcli.recyclerview.MainActivity"> <android.support.v7.widget.RecyclerView android:layout_height="wrap_content" android:layout_width="wrap_content" android:scrollbars="vertical" android:id="@+id/recyclerView" android:layout_marginTop="60dp" android:layout_alignParentLeft="true" android:layout_alignParentStart="true"></android.support.v7.widget.RecyclerView> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add Item" android:id="@+id/button" android:onClick="addRecyclerItem" android:layout_alignParentTop="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/editText" android:textSize="20sp" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_toLeftOf="@+id/button" android:layout_toStartOf="@+id/button" /> </RelativeLayout>創建完布局之后在MainActivity中獲取這個RecyclerView,并聲明
LayoutManager
與Adapter
,代碼如下: mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
//創建默認的線性LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//如果可以確定每個item的高度是固定的,設置這個選項可以提高性能
mRecyclerView.setHasFixedSize(true);
//創建并設置Adapter
mAdapter = newMyAdapter(getData());
mRecyclerView.setAdapter(mAdapter);
getData():private List<String>getDummyDatas()
{List<String> array = new ArrayList<>();for(int i = 0;i<110;i++){array.add("我是"+i);}return array;}
接下來的問題就是Adapter的創建:public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {public List<String> datas = null;public MyAdapter(List<String> datas) {this.datas = datas;}//創建新View,被LayoutManager所調用@Overridepublic 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;}//將數據與界面進行綁定的操作@Overridepublic void onBindViewHolder(ViewHolder viewHolder, int position) {final int index = position;viewHolder.mTextView.setText(datas.get(position));}//獲取數據的數量@Overridepublic int getItemCount() {return datas.size();}//自定義的ViewHolder,持有每個Item的的所有界面元素public static class ViewHolder extends RecyclerView.ViewHolder {public TextView mTextView;public ViewHolder(View view){super(view);mTextView = (TextView) view.findViewById(R.id.textView);}}}
3、運行
寫完這些代碼這個例子既可以跑起來了。從例子也可以看出來,RecyclerView的用法并不比ListView復雜,反而更靈活好用,它將數據、排列方式、數據的展示方式都分割開來,因此可定制型,自定義的形式也非常多,非常靈活。
橫向布局
如果想要一個橫向的List只要設置LinearLayoutManager如下就行,注意要聲明mLayoutManager的類型是LinearLayoutManager而不是父類LayoutManager:
mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
? | ? |
Grid布局
如果想要一個Grid布局的列表,只要聲明LayoutManager為GridLayoutManager即可:
? mLayoutManager?=?
new
?GridLayoutManager(context,columNum);
? mRecyclerView.setLayoutManager(mLayoutManager);
注意,在Grid布局中也可以設置列表的Orientation屬性,來實現橫向和縱向的Grid布局。
瀑布流布局
int span = 3;mLayoutManager = new StaggeredGridLayoutManager(span, StaggeredGridLayoutManager.VERTICAL);mRecyclerView.setLayoutManager(mLayoutManager);
上面介紹的是一個最最簡單的RecyclerView的使用方法,下面將介紹一些更高級的用法
第二節、RecyclerView的高級方法
當使用了一段時間的RecyclerView,發現為其每一項添加點擊事件并沒有ListView那么輕松,像ListView直接加個OnItemClickListener就行了。實際上我們不要把RecyclerView當做ListView的一個升級版,希望大家把他看做一個容器,同時里面包含了很多不同的Item,它們可以以不同方式排列組合,非常靈活,點擊方式你可以按照你自己的意愿進行實現。
本節主要講解如何為RecyclerView添加點擊事件, 并簡單介紹如何進行Item增加刪除。
添加點擊事件
上一節中我們講了如何使用RecyclerView的Adpater,其實我們會發現,Adapter是添加點擊事件一個很好的地方,里面是構造布局等View的主要場所,也是數據和布局進行綁定的地方。首先我們在Adapter中創建一個實現點擊接口,其中view是點擊的Item,data是我們的數據,因為我們想知道我點擊的區域部分的數據是什么,以便我下一步進行操作:
public static interface OnRecyclerViewItemClickListener {void onItemClick(View view , <code class="js plain">DataModel</code> data, int position);}
注:DataModel,這個是一個Objcet ,可能是一個類,也可能是一個String;
定義完接口,添加接口和設置Adapter接口的方法:
private OnRecyclerViewItemClickListener mOnItemClickListener = null;public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {this.mOnItemClickListener = listener;
}
那么這個接口用在什么地方呢?如下代碼所示,我們為Adapter實現OnClickListener方法: @Overridepublic void onBindViewHolder(ViewHolder viewHolder, int position) {final int index = position;viewHolder.mTextView.setText(datas.get(position));//將數據保存在itemView的Tag中,以便點擊時進行獲取//將創建的View注冊點擊事件viewHolder.itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (mOnItemClickListener != null) {//注意這里使用getTag方法獲取數據mOnItemClickListener.onItemClick(v, (String) datas.get(index), index);}}});}
做完這些事情,我們就可以在Activity或其他地方為RecyclerView添加項目點擊事件了,如在MainActivity中: mAdapter.setOnItemClickListener(new MyAdapter.OnRecyclerViewItemClickListener() {@Overridepublic void onItemClick(View view, String data,int position) {}});
完成了以上代碼就可以為RecyclerView添加項目點擊事件了,下面我們來看看RecyclerView如何添加和刪除數據并在界面上顯示。
添加刪除數據
以前在ListView當中,我們只要修改后數據用Adapter的notifyDatasetChange一下就可以更新界面。然而在RecyclerView中還有一些更高級的用法:
添加數據:
public void addItem(DataModel content, int position) {datas.add(position, content);notifyItemInserted(position); //Attention!
}
刪除數據: public void removeItem(int index) {datas.remove(index);notifyItemRemoved(index);//Attention!}
值得注意的是RecyclerView的添加刪除都是有默認的動畫效果的,如果沒有效果可以添加如下代碼:mRecyclerView.setItemAnimator(newDefaultItemAnimator());
當然啦你也可以自己定義你自己的Animator,等我研究明白了也來講一講如何自定義這些效果~
Demo 下載 http://download.csdn.net/detail/q610098308/9326767