目录
1️⃣ 添加 RecyclerView 依赖(Android Studio)
5️⃣ 在 MainActivity 中使用 RecyclerView
第五章:RecyclerView 列表视图与适配器机制
5.1 为什么要使用 RecyclerView?
RecyclerView 是 Android 中用于显示长列表或网格数据的强大控件,相比早期的 ListView 有以下优势:
优势 | 描述 |
---|---|
灵活布局 | 支持线性、网格、瀑布流布局 |
高性能 | 内置“复用机制”,提高性能 |
自定义强 | 可自定义 ViewHolder、动画、分隔线 |
5.2 基本结构图
RecyclerView ├── Adapter(适配器) │ └── ViewHolder(单项视图) └── LayoutManager(布局管理器)
5.3 RecyclerView 使用步骤
假设我们要展示一个简单的字符串列表。
1️⃣ 添加 RecyclerView 依赖(Android Studio)
dependencies {
implementation 'androidx.recyclerview:recyclerview:1.3.1'
}
2️⃣ 布局文件(activity_main.xml)
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
3️⃣ 创建单项布局(item_text.xml)
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textItem"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_vertical"
android:padding="16dp"
android:textSize="18sp"/>
4️⃣ 创建适配器类(MyAdapter.java)
package com.example.myapp;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<String> dataList;
public MyAdapter(List<String> dataList) {
this.dataList = dataList;
}
// ViewHolder:缓存 item 控件
static class MyViewHolder extends RecyclerView.ViewHolder {
TextView textItem;
MyViewHolder(View itemView) {
super(itemView);
textItem = itemView.findViewById(R.id.textItem);
}
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_text, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.textItem.setText(dataList.get(position));
}
@Override
public int getItemCount() {
return dataList.size();
}
}
5️⃣ 在 MainActivity 中使用 RecyclerView
package com.example.myapp;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private MyAdapter adapter;
private List<String> stringList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
stringList = new ArrayList<>();
// 添加测试数据
for (int i = 1; i <= 20; i++) {
stringList.add("第 " + i + " 项");
}
adapter = new MyAdapter(stringList);
recyclerView.setLayoutManager(new LinearLayoutManager(this)); // 垂直列表
recyclerView.setAdapter(adapter);
}
}
5.4 支持点击事件
修改 MyAdapter.java
中的 onBindViewHolder
方法:
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.textItem.setText(dataList.get(position));
holder.textItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "点击了:" + dataList.get(position), Toast.LENGTH_SHORT).show();
}
});
}
5.5 设置不同布局方式
网格布局:
recyclerView.setLayoutManager(new GridLayoutManager(this, 2)); // 2 列
瀑布流布局:
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
5.6 分割线和动画(可选)
添加分割线:
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
✅ 本章小结
概念 | 说明 |
---|---|
RecyclerView | 高效列表展示控件 |
Adapter | 数据适配器,负责绑定数据 |
ViewHolder | 用于提高性能的视图缓存机制 |
LayoutManager | 控制列表排列方式(线性、网格等) |
📌 练习题
修改 Adapter,点击列表项后跳转到新的 Activity 并传递字符串
使用 GridLayoutManager 显示 3 列网格
自定义 item 布局,包括头像、标题、内容三部分
✅ 下一章预告:
第六章:列表数据动态更新与刷新(如添加、删除、SwipeRefresh)
习题答案
项目结构
MainActivity.java
DetailActivity.java
MyAdapter.java
activity_main.xml
activity_detail.xml
item_layout.xml
1. MainActivity.java
package com.example.demo;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private MyAdapter adapter;
private List<ItemModel> itemList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
// 初始化数据
itemList = new ArrayList<>();
itemList.add(new ItemModel("Avatar 1", "Title 1", "Content 1"));
itemList.add(new ItemModel("Avatar 2", "Title 2", "Content 2"));
itemList.add(new ItemModel("Avatar 3", "Title 3", "Content 3"));
itemList.add(new ItemModel("Avatar 4", "Title 4", "Content 4"));
itemList.add(new ItemModel("Avatar 5", "Title 5", "Content 5"));
// 设置 Adapter 和 LayoutManager
adapter = new MyAdapter(itemList, this);
recyclerView.setLayoutManager(new GridLayoutManager(this, 3)); // 3 列网格布局
recyclerView.setAdapter(adapter);
// 设置点击事件监听器
adapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
@Override
public void onItemClick(String title) {
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
intent.putExtra("TITLE", title); // 传递标题
startActivity(intent);
}
});
}
}
2. DetailActivity.java
package com.example.demo;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class DetailActivity extends AppCompatActivity {
private TextView textViewTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
textViewTitle = findViewById(R.id.textViewTitle);
// 获取传递的标题并显示
String title = getIntent().getStringExtra("TITLE");
if (title != null) {
textViewTitle.setText(title);
}
}
}
3. MyAdapter.java
package com.example.demo;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<ItemModel> itemList;
private Context context;
private OnItemClickListener listener;
public MyAdapter(List<ItemModel> itemList, Context context) {
this.itemList = itemList;
this.context = context;
}
// 定义点击事件接口
public interface OnItemClickListener {
void onItemClick(String title);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ItemModel item = itemList.get(position);
holder.textViewTitle.setText(item.getTitle());
holder.textViewContent.setText(item.getContent());
// 模拟头像(可以替换为实际图片加载逻辑)
holder.imageViewAvatar.setImageResource(R.drawable.ic_launcher_foreground);
// 设置点击事件
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onItemClick(item.getTitle());
}
}
});
}
@Override
public int getItemCount() {
return itemList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageViewAvatar;
TextView textViewTitle;
TextView textViewContent;
public ViewHolder(@NonNull View itemView) {
super(itemView);
imageViewAvatar = itemView.findViewById(R.id.imageViewAvatar);
textViewTitle = itemView.findViewById(R.id.textViewTitle);
textViewContent = itemView.findViewById(R.id.textViewContent);
}
}
}
4. ItemModel.java
package com.example.demo;
public class ItemModel {
private String avatar;
private String title;
private String content;
public ItemModel(String avatar, String title, String content) {
this.avatar = avatar;
this.title = title;
this.content = content;
}
public String getAvatar() {
return avatar;
}
public String getTitle() {
return title;
}
public String getContent() {
return content;
}
}
5. activity_main.xml
<?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="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp" />
</LinearLayout>
6. activity_detail.xml
<?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="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="16dp">
<TextView
android:id="@+id/textViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:textSize="24sp" />
</LinearLayout>
7. item_layout.xml
<?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:orientation="vertical"
android:padding="8dp"
android:gravity="center">
<ImageView
android:id="@+id/imageViewAvatar"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="@drawable/ic_launcher_foreground"
android:contentDescription="Avatar" />
<TextView
android:id="@+id/textViewTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:textSize="16sp"
android:gravity="center"
android:paddingTop="4dp" />
<TextView
android:id="@+id/textViewContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Content"
android:textSize="14sp"
android:gravity="center"
android:paddingTop="2dp" />
</LinearLayout>