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,你们有任何技术交流的问题均可以联系我,批评也能够!另外,求工做!