使用 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>
定义数据模型
你可以使用任何类或原始数据类型作为模型,如 int
,String
,float[]
或 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
用于名称。LinearLayout
将 ImageView
定位在左侧,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.Adapter
和 RecyclerView.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));
}