当前位置: 首页 > news >正文

《Android 应用开发基础教程》——第五章:RecyclerView 列表视图与适配器机制

目录

第五章:RecyclerView 列表视图与适配器机制

5.1 为什么要使用 RecyclerView?

5.2 基本结构图

5.3 RecyclerView 使用步骤

1️⃣ 添加 RecyclerView 依赖(Android Studio)

2️⃣ 布局文件(activity_main.xml)

3️⃣ 创建单项布局(item_text.xml)

4️⃣ 创建适配器类(MyAdapter.java)

5️⃣ 在 MainActivity 中使用 RecyclerView

5.4 支持点击事件

5.5 设置不同布局方式

网格布局:

瀑布流布局:

5.6 分割线和动画(可选)

添加分割线:

✅ 本章小结

习题答案

项目结构

1. MainActivity.java

2. DetailActivity.java

3. MyAdapter.java

4. ItemModel.java

5. activity_main.xml

6. activity_detail.xml

7. item_layout.xml

 


第五章: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.RecyclerViewandroid: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);}}@Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_text, parent, false);return new MyViewHolder(view);}@Overridepublic void onBindViewHolder(MyViewHolder holder, int position) {holder.textItem.setText(dataList.get(position));}@Overridepublic 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;@Overrideprotected 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() {@Overridepublic 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控制列表排列方式(线性、网格等)

📌 练习题

  1. 修改 Adapter,点击列表项后跳转到新的 Activity 并传递字符串

  2. 使用 GridLayoutManager 显示 3 列网格

  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;@Overrideprotected 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 和 LayoutManageradapter = new MyAdapter(itemList, this);recyclerView.setLayoutManager(new GridLayoutManager(this, 3)); // 3 列网格布局recyclerView.setAdapter(adapter);// 设置点击事件监听器adapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {@Overridepublic 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;@Overrideprotected 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@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false);return new ViewHolder(view);}@Overridepublic 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() {@Overridepublic void onClick(View v) {if (listener != null) {listener.onItemClick(item.getTitle());}}});}@Overridepublic 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.RecyclerViewandroid: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"><TextViewandroid: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"><ImageViewandroid:id="@+id/imageViewAvatar"android:layout_width="64dp"android:layout_height="64dp"android:src="@drawable/ic_launcher_foreground"android:contentDescription="Avatar" /><TextViewandroid: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" /><TextViewandroid: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>

相关文章:

  • esp32c3 c2如何进入下载模式
  • MCU开发学习记录10 - 高级定时器学习与实践(HAL库)—PWM互补输出、死区控制、刹车控制 - STM32CubeMX
  • Linux Wlan-四次握手(eapol)框架流程
  • CSS预处理工具有哪些?分享主流产品
  • 第二章 Logback的架构(一)
  • eBay自动化定价陷阱调查:价格战背后的利润黑洞与破局之道
  • Oracle expdp的 EXCLUDE 参数详解
  • 如何在LangChain中构建并使用自定义向量数据库
  • 操作指南:在vue-fastapi-admin上增加新的功能模块
  • Qwen-Chat与谷歌Veo2在免费AI视频方面对比
  • Unity3D ILRuntime与Scripting Backend整合指南
  • C++学习之游戏服务器开发十一DOCKER的基本使用
  • 从service 到 JobIntentService 和 WorkManager
  • 香港电讯荣膺“卓越互联网接入服务提供商”奖项,赋能中国汽车产业数字化转型
  • Linux环境准备(安装VirtualBox和Ubuntu,安装MySQL,MySQL启动、重启和停止)
  • KUKA机器人不同的安装方式的设置
  • LeetCode面试经典 150 题(Java题解)
  • C++ vector 核心功能解析与实现
  • TOGAF 敏捷冲刺:15 天 Scrum 冲刺实践
  • 新能源汽车零部件功率级测试方案搭建研究
  • 第三轮上海餐饮消费券本周五起报名,核销时间延长至6月2日
  • “中国共产党的故事——习近平新时代中国特色社会主义思想在重庆的实践”重庆经贸推介会成功举办
  • 史蒂夫·麦奎因透露罹患前列腺癌,呼吁同胞莫受困于男性气概
  • 一年一CT,十年进ICU?关于CT检查致癌的真相
  • 中办、国办印发《农村基层干部廉洁履行职责规定》
  • 女子伸腿阻止高铁关门等待同行人员,相关部门已介入调查