RecyclerView是傳統ListView的一個很好的替代,具備很好的拓展性,初次接觸RecyclerView可能會被其複雜的邏輯搞暈,本文就以一個簡單的實例帶小夥伴們理清其中的關係。java
本文所使用的IDE爲AndroidStudio。android
依次點擊File--->Project Structure--->左下角Module的app--->Dependencis--->點擊左下方的+號,選擇recycler view便可。微信
首先建立一個名爲NotesListFragment的fragment,對應的佈局文件名爲fragment_notes_list。接着將該fragment加入到主Activity中(關於如何在Activity中操做fragment將另做文章說明,此處省略啦),接下來在NotesListFragment中定義一個私有字段app
private RecyclerView noteRecycler;
咱們將要實現的是一個顯示筆記的RecyclerView,這裏將筆記類定義以下:dom
package com.aristark.note; import java.util.Date; import java.util.UUID; public class Note { private UUID uuid; private String title; private String content; private Date date; private String tag; public Note{ uuid = UUID.randomUUID(); date = new Date(); } public UUID getUuid() { return uuid; } public Date getDate() { return date; } public void setTitle(String title) { this.title = title; } public String getTitle() { return title; } public void setContent(String content) { this.content = content; } public String getContent() { return content; } public void setTag(String tag) { this.tag = tag; } public String getTag() { return tag; } }
爲了操做方便,咱們再建立一個NoteLab類:ide
package com.aristark.note; import android.content.Context; import java.util.ArrayList; public class NoteLab { private static NoteLab sNoteLab; //for the global use private ArrayList<Note> notes; private NoteLab(Context context){ notes = new ArrayList<Note>(); //generate 100 Note Objects for (int i=0;i<100;i++){ Note note = new Note(); note.setTitle("this is title "+i); note.setContent("this is content"+i+"balabalabalabalalabalabalabalabalala\nbalabalabalabalalabalabalabala balala\nbalabalabalabalalabalabalabalabalala\nbalabalabalabalalabalabalab alabalala\nbalabalabalabalalabalabalabalabalala\n"); notes.add(note); } } public static NoteLab getNoteLab(Context context){ if (sNoteLab == null){ sNoteLab = new NoteLab(context); } return sNoteLab; } public ArrayList<Note> getNotes() { return notes; } }
注意體會該類所使用的單例模式,sNoteLab以靜態方式存在,既節省了內存,又可讓應用的各個部件方便的訪問。在構造方法NoteLab中,咱們生成100個Note對象以做後面的測試。函數
這兩個類是實現列表的關鍵,其實從字面含義很容易猜想這兩個類的做用,ViewHolder操做的是列表每一個部分的佈局,而Adapter則是用數據去填充View,雖然解釋的不是很準確,但姑且這麼理解是沒問題的。那麼下面咱們就在NotesListFragment裏建立這兩個類:佈局
1 首先建立NoteHolder測試
private class NoteHolder extends RecyclerView.ViewHolder{ public NoteHolder(View root) { super(root); } }
這個類很簡單,值得注意的是自動建立的構造方法所傳入的參數名叫itemView,這裏我將其改成root,由於接下來咱們經過這個構造方法傳進來的是一個完整的佈局文件,而不只僅是一個控件。ui
2 建立Adapter
private class NoteAdapter extends RecyclerView.Adapter<NoteHolder>{ private List<Note> notes; public NoteAdapter(List<Note> notes){ this.notes = notes; } public void setNotes(List<Note> notes) { this.notes = notes; } @Override public NoteHolder onCreateViewHolder(ViewGroup parent, int viewType) { return null; } @Override public void onBindViewHolder(NoteHolder holder, int position) { } @Override public int getItemCount() { return 0; } }
前面說了Adapter是有關於數據的操做了,所以在類的內部定義notes字段也很容易理解,咱們再來看看這裏覆寫的三個方法,onCreateViewHolder返回值是NoteHolder,所以它是用來建立ViewHolder,onBindViewHolder則能夠直接操做NoteHolder,position指的是當前View處在整個List的位置(咱們的目的是要建立相似於微信消息列表的一個列表,其每一個部件的佈局實際上是同樣的,只是填充的數據不同而已),以便按照當前的位置填入相應的數據。getItemCount則是返回須要相應佈局的總數。talk is cheap,show me the code。說再多恐怕也難以表達,下面看代碼,多看幾遍,天然而然就會用了。
private class NoteAdapter extends RecyclerView.Adapter<NoteHolder>{ private List<Note> notes; public NoteAdapter(List<Note> notes){ this.notes = notes; } public void setNotes(List<Note> notes) { this.notes = notes; } @Override public NoteHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(getActivity()); View view = layoutInflater.inflate(R.layout.list_item_note,parent,false); return new NoteHolder(view); } @Override public void onBindViewHolder(NoteHolder holder, int position) { Note note = notes.get(position); holder.bindView(note); } @Override public int getItemCount() { return notes.size(); } }
其中R.layout.list_item_note的佈局文件以下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/list_item_note_title" /> </LinearLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/list_item_note_content" /> </LinearLayout>
這裏只簡單的使用了Note類中title和content兩個字段,其實就是這個view就是造成整個列表,只是依次填充類不一樣的數據而已。
前面已經準備好了ViewHolder和Adapter,接下來要作的就是將這些部件組裝在一塊兒,最後將整個fragment貼出來,你們注意onCreateView裏是 Ruhr操做的!
public class NotesListFragment extends Fragment { private RecyclerView noteRecycler; private NoteAdapter noteAdapter; public NotesListFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment //return inflater.inflate(R.layout.fragment_notes_list, container, false); View root = inflater.inflate(R.layout.fragment_notes_list,container,false); noteRecycler = (RecyclerView) root.findViewById(R.id.note_recycler_view); noteRecycler.setLayoutManager(new LinearLayoutManager(getActivity())); NoteLab noteLab = NoteLab.getNoteLab(getActivity()); ArrayList<Note> notes = noteLab.getNotes(); noteAdapter = new NoteAdapter(notes); noteRecycler.setAdapter(noteAdapter); return root; } private class NoteHolder extends RecyclerView.ViewHolder{ private TextView noteTitle; private TextView noteContent; public NoteHolder(View root) { super(root); noteTitle = (TextView) root.findViewById(R.id.list_item_note_title); noteContent = (TextView) root.findViewById(R.id.list_item_note_content); } public void bindView(Note note){ noteTitle.setText(note.getTitle()); noteContent.setText(note.getContent()); } } private class NoteAdapter extends RecyclerView.Adapter<NoteHolder>{ private List<Note> notes; public NoteAdapter(List<Note> notes){ this.notes = notes; } public void setNotes(List<Note> notes) { this.notes = notes; } @Override public NoteHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(getActivity()); View view = layoutInflater.inflate(R.layout.list_item_note,parent,false); return new NoteHolder(view); } @Override public void onBindViewHolder(NoteHolder holder, int position) { Note note = notes.get(position); holder.bindView(note); } @Override public int getItemCount() { return notes.size(); } } }
最後給你們貼出最後的效果圖吧!
這是我第一次寫博客,解釋的很少,代碼較多,一來是由於我沒有不少表達的經驗,二來我以爲不少時候類名,函數名足以說明它的用途,過多解釋怕會誤導你們。whatever,仍是但願獲得你們的支持,我會在堅持寫代碼的同時也堅持把博客寫下去,是對本身學到的知識的總結,也但願確確實實能夠幫到須要幫助的朋友。個人QQ891871898,你們有任何技術交流的問題均可以聯繫我,批評也能夠!另外,求工做!