RecyclerView簡介與實例

ucvv4952 8年前發布 | 13K 次閱讀 Android開發 移動開發 RecyclerView

來自: https://segmentfault.com/a/1190000004534915

RecyclerView是傳統ListView的一個很好的替代,具有很好的拓展性,初次接觸RecyclerView可能會被其復雜的邏輯搞暈,本文就以一個簡單的實例帶小伙伴們理清其中的關系。

一 添加依賴包

本文所使用的IDE為AndroidStudio。

依次點擊File--->Project Structure--->左下角Module的app--->Dependencis--->點擊左下方的+號,選擇recycler view即可。

二 準備工作

首先創建一個名為NotesListFragment的fragment,對應的布局文件名為fragment_notes_list。接著將該fragment加入到主Activity中(關于如何在Activity中操作fragment將另作文章說明,此處省略啦),接下來在NotesListFragment中定義一個私有字段

private RecyclerView noteRecycler;

我們將要實現的是一個顯示筆記的RecyclerView,這里將筆記類定義如下:

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;
}

}</pre>

為了操作方便,我們再創建一個NoteLab類:

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;
}

}</pre>

注意體會該類所使用的單例模式,sNoteLab以靜態方式存在,既節省了內存,又可以讓應用的各個部件方便的訪問。在構造方法NoteLab中,我們生成100個Note對象以作后面的測試。

三 ViewHolder和Adapter

這兩個類是實現列表的關鍵,其實從字面含義很容易猜測這兩個類的作用,ViewHolder操作的是列表每個部分的布局,而Adapter則是用數據去填充View,雖然解釋的不是很準確,但姑且這么理解是沒問題的。那么下面我們就在NotesListFragment里創建這兩個類:

1 首先創建NoteHolder

private class NoteHolder extends RecyclerView.ViewHolder{

public NoteHolder(View root) {
    super(root);
}       

}</pre>

這個類很簡單,值得注意的是自動創建的構造方法所傳入的參數名叫itemView,這里我將其改為root,因為接下來我們通過這個構造方法傳進來的是一個完整的布局文件,而不僅僅是一個控件。

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;
}

}</pre>

前面說了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();
}

}</pre>

其中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></pre>

這里只簡單的使用了Note類中title和content兩個字段,其實就是這個view就是形成整個列表,只是依次填充類不同的數據而已。

四 RecyclerView的使用

前面已經準備好了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();
    }
}

}</pre>

后記

最后給大家貼出最后的效果圖吧!

這是我第一次寫博客,解釋的不多,代碼較多,一來是因為我沒有很多表達的經驗,二來我覺得很多時候類名,函數名足以說明它的用途,過多解釋怕會誤導大家。whatever,還是希望得到大家的支持,我會在堅持寫代碼的同時也堅持把博客寫下去,是對自己學到的知識的總結,也希望確確實實可以幫到需要幫助的朋友。我的QQ891871898,大家有任何技術交流的問題都可以聯系我,批評也可以!另外,求工作!

</div>

 本文由用戶 ucvv4952 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!