標籤:
轉載請註明出處:http://blog.csdn.net/allen315410/article/details/40379159
萬眾矚目的android最新5.0版本號碼不久前已經正式公布了,對於我這樣對新事物不感冒的人來說,自然也是會關注的,除了新的android5.0帶來的新的UI設計和使用者體驗之外,最讓android程式猿感興趣的是5.0版本號碼的sdk和一大堆新的API。5.0據說是額外添加或者改動了5000個API,新增了一些新的組件,以下介紹的RecyclerView就是當中之中的一個,有人說Google設計出的RecyclerView是為了替代一直經常使用的ListView的,所以既然如此,我們就沒理由不看看這個“傳說”中的RecyclerView是怎麼使用的了。
RecyclerView簡單介紹
該RecyclerView widget是一種更先進的柔性版的ListView。這個小工具是一個容器,用於顯示,能很有效地維護了意見數量有限,滾動大的資料集。使用 RecyclerView當你擁有的資料的集合,它的元素在執行時改變基於使用者行為和網路事件的小組件。
該RecyclerView類簡化,提供顯示和處理大資料集:
定位項目布局管理器
預設的動畫為公用項的操作,比如刪除或添加的項目
您還能夠在自己定義的布局管理器和動畫的靈活性RecyclerView組件。
要使用RecyclerView小組件,你必須指定一個適配器和一個布局管理器。要建立一個適配器,擴充RecyclerView.Adapter類。實施的細節取決於你的資料集的詳細情況和意見的類型。欲瞭解很多其它資訊,請參見示比例如以下。
布局管理器 A的內部位置的項目意見RecyclerView,並確定何時再利用項目的看法不再對使用者可見。重用(或回收)的圖,布局管理器可能會問適配器與資料集不同的元素替換視圖的內容。以這樣的方式回收的觀點提高通過避免產生不必要的視圖或運行昂貴效能findViewById()的尋找。
RecyclerView提供這些內建的布局管理器:
LinearLayoutManager 顯示在垂直或水平滾動清單項目。
GridLayoutManager 顯示在網格中的項目。
StaggeredGridLayoutManager 顯示了交錯網格項目。
要建立自己定義布局管理器,擴充RecyclerView.LayoutManager類。
動畫
動畫的加入和刪除項目中預設啟用的RecyclerView。要自己定義這些動畫,延長 RecyclerView.ItemAnimator類,並使用RecyclerView.setItemAnimator() 方法。
以上內容來自Google官方文檔的翻譯,翻譯比較生澀(我這英文水平,哎~~對付自己還行),以下直接上一個Demo看看詳細的使用方法。
RecyclerView的使用方法
以下簡介製作一個小Demo,來一步步分析一下RecyclerView的使用方法。首先說明一下,RecyclerView是android.support.v7包下提供的組件,所以須要使用RecyclerView時,須要下載這個包,因為我已經將SDK升級到最新版本號碼——API21,所以非常easy在/sdk/extras/android/support/v7/appcompat/libs檔案夾下找到這個jar以及原始碼,建議先升級sdk,再動手做!實在不想動手的下載的,點擊博文下方的連結下載原始碼,原始碼裡有RecyclerView的JAR包。
主介面布局,activity_main.xml
<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" > <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="80dp" android:layout_centerVertical="true" android:background="@android:color/transparent" android:scrollbars="none" /></RelativeLayout>
Item布局,item_recyclerview.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="120dp" android:layout_height="120dp" > <ImageView android:id="@+id/iv_image" android:layout_width="80dp" android:layout_height="80dp" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:scaleType="centerCrop" /></RelativeLayout>
RecyclerView的資料配接器,MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {private int[] mDataset; // 外面傳入的資料public static class ViewHolder extends RecyclerView.ViewHolder {ImageView mImageView;// TODO Auto-generated method stubpublic ViewHolder(View v) {super(v);}}public MyAdapter(int[] mDataset) {this.mDataset = mDataset;}/** * 擷取總的條目數量 */@Overridepublic int getItemCount() {// TODO Auto-generated method stubreturn mDataset.length;}/** * 建立ViewHolder */@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {// TODO Auto-generated method stubView v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycleview, parent, false);ViewHolder holder = new ViewHolder(v);holder.mImageView = (ImageView) v.findViewById(R.id.iv_image);return holder;}/** * 將資料繫結到ViewHolder上 */@Overridepublic void onBindViewHolder(ViewHolder holder, int position) {// TODO Auto-generated method stubholder.mImageView.setImageResource(mDataset[position]);}} 從上面能夠看出這個資料配接器跟ListView用的BaseAdapter上比,已經發生了非常大的變化。首先資料配接器須要繼承RecyclerView.Adapter<VH>類,該類是個泛型類,泛型型別也是ViewHolder,這個ViewHolder毋庸置疑就是實現組件複用的,Google已經幫我們定義好了,在RecyclerView裡是個內部類,可是詳細實現還是扔給android App開發人員去實現,須要在適配器類建立一個內部類,而且繼承RecyclerView,ViewHolder,在這個內部類裡面定義出Item布局上全部須要複用的組件,最後將這個內部類作為泛型傳遞給RecyclerView.Adapter<VH>,實現須要複寫的3個方法:
getItemCount() 擷取Item的總數。
onCreateViewHolder(ViewGroup parent, int viewType) 建立ViewHolder。
onBindViewHolder(ViewHolder holder, int position) 將資料繫結到ViewHolder。
與ListView資料適配的對照
ListView裡面有個getView()方法返回的View是Item的布局,那麼這個RecyclerView的Item的布局在哪控制?事實上是這種,RecyclerView對ViewHolder也進行了一定的封裝,我們建立的ViewHolder必須繼承RecyclerView.ViewHolder,這個RecyclerView.ViewHolder的構造時必須傳入一個View,這個View相當於我們ListView的getView()中的convertView (即:我們須要inflate的item布局須要傳入)。
另一點,ListView中convertView是複用的,在RecyclerView中,是把ViewHolder作為緩衝的單位了,然後convertView作為ViewHolder的成員變數保持在ViewHolder中,也就是說,如果沒有螢幕顯示10個條目,則會建立10個ViewHolder緩衝起來,每次複用的是ViewHolder,所以他把getView這種方法變為了onCreateViewHolder。
最後,就在Activity裡使用這個RecyclerView,MainActivity.java
public class MainActivity extends Activity {/** RecyclerView對象 */private RecyclerView recyclerView;/** 圖片資源 */private int[] mDataset;/** 資料配接器 */private MyAdapter mAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);recyclerView = (RecyclerView) findViewById(R.id.recyclerview);// 初始化圖片資料mDataset = new int[] { R.drawable.a, R.drawable.b, //R.drawable.c, R.drawable.d, R.drawable.e, //R.drawable.f, R.drawable.g, R.drawable.h, R.drawable.i };// 設定布局管理器LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);recyclerView.setLayoutManager(linearLayoutManager);// 設定適配器mAdapter = new MyAdapter(mDataset);recyclerView.setAdapter(mAdapter);}}
在MainActivity使用RecyclerView如同使用ListView一樣的簡單,唯一不同的地方就是,須要給RecyclerView設定一個布局管理器,Google為我們提供了3種不同的布局管理(具體請看最上面的簡單介紹),這裡我使用的LinearLayoutmanager,而且設定布局為水平顯示。 好了,關於RecyclerView的基本使用方法講完了,那個關於RecyclerView的另外兩個布局管理器就臨時不說了,大同小異。以下是執行
為RecyclerView設定事件回調
再使用RecyclerView組件時,發現了一個令人“痛心疾首”的問題:RecyclerView竟然沒有點擊Item的事件監聽設定,類似於ListView中起碼有個setOnItemClickListener方法,用於監聽Item點擊並作出對應的邏輯處理。可是翻遍了RecyclerView的API,都沒有發現這個或者類似這個功能的方法可用,這不得不說是個“悲劇”,還聽說這個是為了替代ListView的,看來並非這種,請Google出來解釋解釋啊!
好了,Google應該最近是不會解釋的了,可是我們得自己想辦法解決問題,就是為RecyclerView加入一個回呼函數,這個倒不難吧!實在無法領會的,能夠看看我前面的那篇博文,Android自己定義組件——仿ios滑動button,裡面有一些相關的使用方法。以下是我在Adapter裡加入的回呼函數。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {private int[] mDataset; // 外面傳入的資料/** * Item的回調介面 * */public interface OnItemClickListener {void onItemClickListener(View view, int position);}private OnItemClickListener listener; // 點擊Item的回調對象/** * 設定回調監聽 * * @param listener */public void setOnItemClickListener(OnItemClickListener listener) {this.listener = listener;}public static class ViewHolder extends RecyclerView.ViewHolder {ImageView mImageView;// TODO Auto-generated method stubpublic ViewHolder(View v) {super(v);}}public MyAdapter(int[] mDataset) {this.mDataset = mDataset;}/** * 擷取總的條目數量 */@Overridepublic int getItemCount() {// TODO Auto-generated method stubreturn mDataset.length;}/** * 建立ViewHolder */@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {// TODO Auto-generated method stubView v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycleview, parent, false);ViewHolder holder = new ViewHolder(v);holder.mImageView = (ImageView) v.findViewById(R.id.iv_image);return holder;}/** * 將資料繫結到ViewHolder上 */@Overridepublic void onBindViewHolder(ViewHolder holder, final int position) {// TODO Auto-generated method stubholder.mImageView.setImageResource(mDataset[position]);if (listener != null) {holder.mImageView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {listener.onItemClickListener(v, position);}});}}}首先在Adapter裡定義一個內部介面,介面內定義回呼函數,然後向外暴露一個設定這個介面對象的方法,通過這種方法設定內部介面的對象,最後在ViewHolder綁定資料的方法中,通過介面對象調用介面方法,將相關資訊傳遞出去。以下是在MainActivity裡設定這個監聽方法:
mAdapter.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClickListener(View view, int position) {// TODO Auto-generated method stubToast.makeText(MainActivity.this, position + "", Toast.LENGTH_SHORT).show();}});下面是執行:
原始碼請在這裡下載
Android最新組件RecyclerView,替代ListView