使用 LinearLayoutManager 的簡單列表

此示例通過使用 ArrayList 自定義 Place 物件作為資料集新增具有影象和名稱的位置列表。

活動佈局

活動/片段的佈局或使用 RecyclerView 的佈局只需包含 RecyclerView。沒有 ScrollView 或需要特定的佈局。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

定義資料模型

你可以使用任何類或原始資料型別作為模型,如 intStringfloat[]CustomObject。RecyclerView 將引用此物件/基元的 List

當列表項引用不同的資料型別(如文字,數字,影象)時(如本例中的地點所示),使用自定義物件通常是個好主意。

public class Place {
    // these fields will be shown in a list item
    private Bitmap image;
    private String name;

    // typical constructor
    public Place(Bitmap image, String name) {
        this.image = image;
        this.name = name;
    }

    // getters
    public Bitmap getImage() {
        return image;
    }
    public String getName() {
        return name;
    } 
}

列出專案佈局

你必須指定將用於每個列表項的 xml 佈局檔案。在這個例子中,ImageView 用於影象,TextView 用於名稱。LinearLayoutImageView 定位在左側,TextView 定位在影象右側。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:padding="8dp">

    <ImageView
        android:id="@+id/image"
        android:layout_width="36dp"
        android:layout_height="36dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp" />

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

建立 RecyclerView 介面卡和 ViewHolder

接下來,你必須繼承 RecyclerView.AdapterRecyclerView.ViewHolder。通常的類結構是:

public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
    // ...

    public class ViewHolder extends RecyclerView.ViewHolder {
        // ...
    }
}

首先,我們實施 ViewHolder。它只繼承預設建構函式並將所需的檢視儲存到某些欄位中:

public class ViewHolder extends RecyclerView.ViewHolder {
    private ImageView imageView;
    private TextView nameView;

    public ViewHolder(View itemView) {
        super(itemView);

        imageView = (ImageView) itemView.findViewById(R.id.image);
        nameView = (TextView) itemView.findViewById(R.id.name);
    }
}

介面卡的建構函式設定使用的資料集:

public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
    private List<Place> mPlaces;

    public PlaceListAdapter(List<Place> contacts) {
        mPlaces = contacts;
    }

    // ...
}

要使用我們的自定義列表項佈局,我們重寫方法 onCreateViewHolder(...)。在此示例中,佈局檔名為 place_list_item.xml

public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
    // ...

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.place_list_item,
                parent,
                false
        );
        return new ViewHolder(view);
    }

    // ...
}

onBindViewHolder(...) 中,我們實際設定了檢視的內容。我們通過在給定位置的 List 中找到它來獲得使用的模型,然後在 ViewHolder 的檢視上設定影象和名稱。

public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
    // ...

    @Override
    public void onBindViewHolder(PlaceListAdapter.ViewHolder viewHolder, int position) {
        Place place = mPlaces.get(position);

        viewHolder.nameView.setText(place.getName());
        viewHolder.imageView.setImageBitmap(place.getImage());
    }

    // ...
}

我們還需要實現 getItemCount(),它只返回 List 的大小。

public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.ViewHolder> {
    // ...

    @Override
    public int getItemCount() {
        return mPlaces.size();
    }

    // ...
}

(生成隨機資料)

對於這個例子,我們將生成一些隨機的地方。

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...

    List<Place> places = randomPlaces(5);

    // ...
}

private List<Place> randomPlaces(int amount) {
    List<Place> places = new ArrayList<>();
    for (int i = 0; i < amount; i++) {
        places.add(new Place(
                BitmapFactory.decodeResource(getResources(), Math.random() > 0.5 ?
                        R.drawable.ic_account_grey600_36dp :
                        R.drawable.ic_android_grey600_36dp
                ),
                "Place #" + (int) (Math.random() * 1000)
        ));
    }
    return places;
}

將 RecyclerView 與 PlaceListAdapter 和資料集連線起來

RecyclerView 與介面卡連線非常容易。你必須將 LinearLayoutManager 設定為佈局管理器才能實現列表佈局。

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
    recyclerView.setAdapter(new PlaceListAdapter(places));
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
}

完成!