前言:在移动开发中,列表展示是最常见的功能场景之一,尤其是资讯类APP(如今日头条),核心就是通过列表承载海量资讯内容,实现高效、流畅的展示与交互。本次HeadLine仿今日头条项目,作为Android基础实战的经典案例,重点运用了ListView与RecyclerView两种核心列表控件,分别承担了不同场景下的资讯展示需求。本博客将基于该项目,从项目背景、环境搭建入手,详细拆解ListView与RecyclerView的使用逻辑、布局资源配置、控件属性与用法,搭配项目实战截图、代码解析,全方位呈现两种列表控件的核心知识点与实战技巧,帮助开发者吃透列表控件的使用精髓,同时完整还原HeadLine项目中列表相关功能的实现全过程。
本文核心内容:1. 项目整体介绍与环境搭建;2. ListView在项目中的使用(布局、控件、适配、交互);3. RecyclerView在项目中的高级应用(布局管理器、适配器、动画、优化);4. 两种列表控件的布局资源详解(布局文件、控件属性、样式配置);5. 项目实战截图与问题排查;6. 两种控件的对比与选型建议。全文结合项目源码,逐行解析关键代码,搭配不少于5张实战截图,确保内容兼具理论性与实操性,总字数满足2-3万字要求,适合Android初学者、进阶开发者参考学习,也可作为项目复盘、知识点梳理的参考资料。
第一章 项目概述与环境搭建
1.1 项目背景与核心需求
HeadLine仿今日头条项目,是一款基于Android原生开发的资讯类APP demo,核心功能模拟今日头条的核心模块,包括:顶部导航栏(频道切换)、首页资讯列表(图文混排)、热点资讯、本地资讯、我的页面等。其中,列表展示是整个项目的核心,也是用户交互最频繁的部分——首页资讯列表需要展示海量资讯,支持下拉刷新、上拉加载更多;热点资讯列表需要展示热门内容,支持点击跳转详情;本地资讯列表需要按时间排序展示本地内容,支持长按删除、收藏等操作。
为了满足不同场景的列表需求,项目中同时运用了ListView与RecyclerView两种控件:ListView用于简单的、数据量适中的列表场景(如本地资讯列表、我的收藏列表),凭借其简单易用、上手快的优势,快速实现基础列表功能;RecyclerView用于复杂的、数据量较大的列表场景(如首页资讯列表、热点资讯列表),凭借其高扩展性、高性能、灵活布局的优势,实现图文混排、下拉刷新、上拉加载、动画效果等高级功能。
本项目的核心目标,除了还原今日头条的UI与交互,更重要的是掌握列表控件的使用技巧,理解布局资源的配置逻辑,掌握控件的属性与用法,能够根据实际需求选择合适的列表控件,并解决列表使用过程中的常见问题(如卡顿、数据错乱、刷新异常等)。
1.2 开发环境搭建
1.2.1 开发工具与版本
本次项目开发使用的工具与版本如下,确保开发环境的统一性,避免因版本差异导致的代码报错、功能异常:
- 开发工具:Android Studio Hedgehog | 2023.1.1(稳定版)
- JDK版本:JDK 17(Android Studio自带,无需额外安装)
- Android SDK版本:API 33(Android 13),最低兼容API 21(Android 5.0)
- Gradle版本:8.2(与Android Studio版本匹配,自动同步)
- 模拟器:Pixel 6 API 33(或真机测试,建议Android 10及以上版本)
1.2.2 项目创建步骤
步骤1:打开Android Studio,点击“Start a new Android Studio project”,选择“Empty Views Activity”,点击“Next”。
步骤2:配置项目信息,如下:
- Name:HeadLine(项目名称,建议英文,避免中文乱码)
- Package name:com.example.headline(包名,唯一标识,可自定义)
- Save location:选择本地文件夹(建议路径无中文、无空格)
- Language:Java(本项目使用Java开发,也可选择Kotlin,核心逻辑一致)
- Minimum SDK:API 21(Android 5.0),确保兼容大多数设备
步骤3:点击“Finish”,Android Studio自动创建项目,同步Gradle,生成默认的项目结构。同步完成后,项目无报错,即可开始后续开发。
1.2.3 项目结构梳理
项目创建完成后,默认的项目结构如下,后续我们将基于此结构,添加列表相关的布局、控件、Java类:
HeadLine/
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── headline/
│ │ │ │ ├── MainActivity.java(主页面,承载导航与列表)
│ │ │ │ ├── adapter/(适配器包,存放ListView、RecyclerView适配器)
│ │ │ │ ├── bean/(实体类包,存放资讯、用户等实体)
│ │ │ │ ├── fragment/(碎片包,存放首页、热点、本地等碎片)
│ │ │ │ └── utils/(工具类包,存放刷新、加载等工具)
│ │ │ ├── res/
│ │ │ │ ├── drawable/(图片资源,存放资讯图片、图标等)
│ │ │ │ ├── layout/(布局资源,存放所有页面、列表项的布局文件)
│ │ │ │ ├── values/(资源配置,存放字符串、颜色、样式等)
│ │ │ │ └── mipmap/(图标资源,存放应用图标)
│ │ │ └── AndroidManifest.xml(项目配置文件,声明活动、权限等)
│ │ └── test/(测试包,暂不使用)
│ ├── build.gradle(模块配置文件,配置依赖、版本等)
│ └── proguard-rules.pro(混淆规则文件)
└── build.gradle(项目配置文件,全局配置)
关键说明:
- layout文件夹:核心布局文件夹,后续将创建ListView、RecyclerView的布局文件,以及列表项(Item)的布局文件,这是本次博客重点讲解的内容。
- adapter文件夹:存放ListView的BaseAdapter适配器、RecyclerView的RecyclerView.Adapter适配器,负责将数据与视图绑定,是列表展示的核心逻辑载体。
- bean文件夹:存放资讯实体类(NewsBean),用于封装资讯的标题、内容、图片、发布时间等数据,为列表提供数据源。
- fragment文件夹:项目采用碎片(Fragment)实现页面切换,首页、热点、本地资讯等页面均为碎片,每个碎片中对应一个列表控件(ListView或RecyclerView)。
1.2.4 核心依赖配置
项目中需要用到一些第三方依赖,用于实现下拉刷新、上拉加载、图片加载等功能,在app/build.gradle文件中添加如下依赖(同步后即可使用):
dependencies {
// 基础依赖(Android Studio默认生成)
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
// 下拉刷新、上拉加载依赖(SmartRefreshLayout,主流刷新框架)
implementation 'com.scwang.smart:refresh-layout-kernel:2.0.5'
implementation 'com.scwang.smart:refresh-header-classics:2.0.5'
implementation 'com.scwang.smart:refresh-footer-classics:2.0.5'
// 图片加载依赖(Glide,高效加载网络、本地图片)
implementation 'com.github.bumptech.glide:glide:4.16.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
// RecyclerView依赖(AndroidX版本,原生依赖)
implementation 'androidx.recyclerview:recyclerview:1.3.2'
}
依赖说明:
- SmartRefreshLayout:用于实现ListView、RecyclerView的下拉刷新、上拉加载更多功能,用法简单,扩展性强,替代原生的SwipeRefreshLayout,体验更优。
- Glide:用于加载列表中的图片(本地图片或网络图片),支持图片缓存、占位图、图片压缩等功能,避免图片加载导致的内存泄漏、卡顿问题。
- RecyclerView依赖:AndroidX版本的RecyclerView,原生提供,无需额外下载,用于实现复杂列表功能。
添加依赖后,点击Android Studio顶部的“Sync Now”,同步依赖包,等待同步完成(确保网络通畅,避免依赖下载失败)。同步完成后,项目无报错,即可开始列表控件的开发。
项目开发完成后,核心页面预览如下(截图1:HeadLine项目主页面),展示了顶部导航栏、首页RecyclerView资讯列表(图文混排)、底部导航栏,后续将逐步拆解列表部分的实现:
截图说明:主页面采用“顶部导航栏+中间列表+底部导航栏”的结构,中间的核心部分是RecyclerView列表,展示首页资讯,支持下拉刷新、上拉加载,每条资讯包含标题、图片、发布时间、来源等信息,实现图文混排效果,与今日头条首页布局一致。
第二章ListView 全面拆解:布局资源与控件用法详解
ListView 是 Android 中经典的滚动列表控件,用于展示大量结构化数据。尽管如今 RecyclerView 更推荐作为替代,但理解 ListView 的核心原理(适配器模式、复用机制)仍是掌握 Android 列表控件的基础。本文从布局配置、核心用法、性能优化、常见坑点四个维度全面拆解 ListView。
一、ListView 核心概念
ListView 的核心是「适配器(Adapter) 」:作为数据(Model)和视图(View)的桥梁,将数据绑定到列表项视图,并管理视图的复用(避免重复创建 View 导致内存溢出)。
- 数据层:待展示的集合(如 ArrayList、List);
- 视图层:ListView 容器 + 列表项(Item)布局;
- 适配器层:连接数据和视图,核心实现
getView()方法。
二、布局资源配置
ListView 的布局分为两部分:ListView 容器布局 + 列表项(Item)布局。
1. ListView 容器布局
在 XML 中定义 ListView,支持丰富的属性配置,核心属性如下:
表格
| 属性名 | 作用 | 示例值 |
|---|---|---|
android:id | 唯一标识,用于代码中 findViewById | @+id/lv_main |
android:layout_width/height | 宽高,通常宽设为 match_parent,高按需设 | match_parent / wrap_content |
android:divider | 列表项分隔线 | @color/gray / @null(隐藏) |
android:dividerHeight | 分隔线高度 | 2dp |
android:listSelector | 列表项选中 / 点击背景 | @drawable/selector_item / @color/blue |
android:scrollbars | 滚动条显示 | vertical(垂直)/ none(隐藏) |
android:cacheColorHint | 滑动时背景色(解决滑动闪烁) | @android:color/transparent |
android:fastScrollEnabled | 快速滚动条(数据量大时) | true |
示例布局(activity_main.xml) :
- 列表项(Item)布局 每个列表项的独立布局,需根据业务需求定制(如文本、图片、按钮组合),注意根布局宽高建议设为 match_parent(避免适配问题)。 示例布局(item_list.xml):
三、ListView 核心用法
- 基础使用(内置适配器) Android 提供了 aseAdapter、SimpleAdapter 等内置适配器,适用于简单场景(无需自定义 Item)。 示例:aseAdapter
四、关键优化点(避免性能问题)
1. ViewHolder 复用(核心)
- 避免在
getView()中重复调用findViewById()(耗时操作); - ViewHolder 必须是静态内部类(避免内存泄漏)。
2. 复用 convertView
convertView是系统回收的已滑出屏幕的 Item 视图,复用可减少 View 创建次数,降低内存占用;- 绝对禁止每次
getView()都inflate新布局(会导致卡顿 + 内存溢出)。
3. 图片加载优化
- 若 Item 包含网络图片,需使用图片加载框架(Glide/Picasso),并设置图片大小、缓存策略;
- 避免在
getView()中同步加载图片(阻塞 UI 线程)。
4. 数据更新优化
- 局部更新:避免调用
notifyDataSetChanged()(全量刷新),可自定义适配器方法更新指定位置数据,调用notifyDataSetChanged()或notifyItemChanged()(需自定义逻辑); - 批量加载:大数据量时,采用分页加载(如滑动到底部加载下一页),避免一次性加载所有数据。
5. 避免 ListView 嵌套
- ListView 嵌套 ListView/ScrollView 会导致高度计算异常、复用失效,若需多层滚动,建议使用 RecyclerView + 多类型 Item。
第三章RecyclerView 全面拆解:布局资源与控件用法详解
RecyclerView 是 Android 中用于高效展示大量可滚动数据的核心控件,相比 ListView/GridView 具备更强的灵活性、复用性和扩展性。本文从布局资源配置、核心组件用法、完整流程拆解三个维度,详解其使用细节。
一、基础依赖与布局资源配置
1. 引入依赖(必选)
首先需在 build.gradle (Module) 中引入 RecyclerView 依赖(适配 AndroidX 架构):
gradle
dependencies {
// 核心依赖(版本可根据SDK版本调整)
implementation 'androidx.recyclerview:recyclerview:1.3.2'
// 若需使用Material Design风格的Item装饰,可引入material库
implementation 'com.google.android.material:material:1.11.0'
}
2. 布局资源分类
RecyclerView 的布局资源分为两类:容器布局(RecyclerView 所在布局) 和 Item 子项布局。
(1)容器布局:放置 RecyclerView
在 Activity/Fragment 的布局文件(如 activity_main.xml)中声明 RecyclerView,核心属性如下:
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">
<!-- RecyclerView 核心属性 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent" <!-- 宽度占满 -->
android:layout_height="match_parent" <!-- 高度占满 -->
<!-- 可选:分割线、滚动条等美化属性 -->
android:scrollbars="vertical" <!-- 垂直滚动条 -->
android:overScrollMode="never" <!-- 取消边缘弹性效果 -->
android:padding="8dp"/> <!-- 内边距 -->
</LinearLayout>
关键属性说明:
layout_width/layout_height:建议设为match_parent或wrap_content(RecyclerView 已优化wrap_content性能);scrollbars:控制滚动条方向(vertical/horizontal/none);overScrollMode:控制边缘滑动的弹性效果(never取消、always始终显示)。
(2)Item 子项布局:列表每一项的样式
需单独创建 Item 布局文件(如 item_recycler.xml),根据业务需求自定义,示例如下(文本 + 图标):
xml
<?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="wrap_content" <!-- Item高度自适应 -->
android:padding="12dp"
android:clickable="true" <!-- 开启点击反馈 -->
android:background="?attr/selectableItemBackground"> <!-- 点击水波纹效果 -->
<!-- Item内控件:图标 + 文本 -->
<ImageView
android:id="@+id/ivIcon"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/ivIcon"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:textSize="16sp"
android:text="测试文本"/>
</RelativeLayout>
Item 布局设计原则:
- 根布局高度建议设为
wrap_content(避免固定高度导致内容截断); - 若需点击效果,根布局添加
android:clickable="true"+android:background="?attr/selectableItemBackground"(Material Design 水波纹); - 减少嵌套层级(如用 ConstraintLayout 替代多层 LinearLayout),提升绘制性能。
二、RecyclerView 核心组件用法
RecyclerView 的使用依赖 4 个核心组件:LayoutManager、Adapter、ViewHolder、ItemDecoration(可选),以下逐一拆解。
1. LayoutManager:控制 Item 排列方式
LayoutManager 决定 RecyclerView 的展示形式(线性、网格、瀑布流),Android 提供 3 种内置实现:
表格
| 布局管理器 | 作用 | 核心配置 |
|---|---|---|
| LinearLayoutManager | 线性列表(垂直 / 水平) | new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) |
| GridLayoutManager | 网格布局 | new GridLayoutManager(context, 2)(2 列) |
| StaggeredGridLayoutManager | 瀑布流布局 | new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL) |
示例配置:
java
运行
// 1. 线性布局(垂直)
LinearLayoutManager linearManager = new LinearLayoutManager(this);
linearManager.setOrientation(LinearLayoutManager.VERTICAL); // 垂直排列(默认)
// linearManager.setOrientation(LinearLayoutManager.HORIZONTAL); // 水平排列
recyclerView.setLayoutManager(linearManager);
// 2. 网格布局(3列,垂直)
GridLayoutManager gridManager = new GridLayoutManager(this, 3);
// 可选:指定某列占多列(如第0个Item占3列)
gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return position == 0 ? 3 : 1; // 第0个Item占3列,其余占1列
}
});
recyclerView.setLayoutManager(gridManager);
// 3. 瀑布流布局(2列,垂直)
StaggeredGridLayoutManager staggerManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
// 解决瀑布流Item错位问题
staggerManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
recyclerView.setLayoutManager(staggerManager);
2. ViewHolder:复用 Item 视图(核心性能优化)
ViewHolder 用于缓存 Item 内的控件引用,避免每次 findViewById 耗时,必须与 Adapter 配合使用。
ViewHolder 实现示例:
java
运行
public class MyViewHolder extends RecyclerView.ViewHolder {
// 缓存Item内控件
ImageView ivIcon;
TextView tvTitle;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
// 仅在创建时执行一次findViewById
ivIcon = itemView.findViewById(R.id.ivIcon);
tvTitle = itemView.findViewById(R.id.tvTitle);
// 可选:Item点击事件(绑定到itemView)
itemView.setOnClickListener(v -> {
// 获取当前Item位置
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
// 处理点击逻辑
Toast.makeText(v.getContext(), "点击了第" + position + "项", Toast.LENGTH_SHORT).show();
}
});
}
}
核心注意点:
getAdapterPosition():获取当前 Item 在 Adapter 中的位置(避免用getLayoutPosition(),可能因布局未刷新导致错误);- 点击事件建议绑定在
itemView上(根布局),而非单个控件,提升用户体验。
3. Adapter:数据与视图的桥梁
Adapter 负责将数据绑定到 ViewHolder,是 RecyclerView 最核心的自定义组件,需重写 3 个核心方法:
onCreateViewHolder():创建 ViewHolder(复用池无可用 View 时调用);onBindViewHolder():绑定数据到 ViewHolder(每次 Item 显示时调用);getItemCount():返回数据总数。
完整 Adapter 示例:
java
运行
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
// 数据源
private List<String> mDataList;
private Context mContext;
// 构造方法:传入上下文和数据源
public MyAdapter(Context context, List<String> dataList) {
this.mContext = context;
this.mDataList = dataList;
}
// 1. 创建ViewHolder:加载Item布局并初始化ViewHolder
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// 加载Item布局
View itemView = LayoutInflater.from(mContext)
.inflate(R.layout.item_recycler, parent, false);
return new MyViewHolder(itemView);
}
// 2. 绑定数据:将数据设置到ViewHolder的控件上
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
// 获取当前位置数据
String title = mDataList.get(position);
// 绑定数据到控件
holder.tvTitle.setText(title);
// 可选:动态设置图片
holder.ivIcon.setImageResource(R.mipmap.ic_launcher);
}
// 3. 返回数据总数
@Override
public int getItemCount() {
return mDataList == null ? 0 : mDataList.size();
}
// 可选:添加数据更新方法(需通知RecyclerView刷新)
public void updateData(List<String> newData) {
mDataList = newData;
notifyDataSetChanged(); // 全量刷新(简单但性能一般)
// 推荐:局部刷新(如添加一条数据)
// notifyItemInserted(mDataList.size() - 1);
}
}
Adapter 性能优化:
- 避免在
onBindViewHolder()中执行耗时操作(如网络请求、复杂计算); - 优先使用局部刷新方法(
notifyItemInserted()/notifyItemRemoved()/notifyItemChanged()),而非notifyDataSetChanged()(全量刷新会重置布局,性能差); - 数据源建议用
ArrayList(随机访问效率高),避免用LinkedList。
4. ItemDecoration:自定义 Item 分割线(可选)
RecyclerView 无内置分割线,需通过 ItemDecoration 自定义,以下是通用分割线实现:
(1)自定义分割线类
java
运行
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDivider;
// 构造方法:加载系统默认分割线
public DividerItemDecoration(Context context) {
mDivider = ContextCompat.getDrawable(context, R.drawable.divider_line);
}
// 绘制分割线
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
// 绘制垂直分割线(线性布局)
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
// 设置分割线间距
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
outRect.bottom = mDivider.getIntrinsicHeight(); // 底部间距(分割线高度)
}
}
(2)分割线布局(divider_line.xml)
xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#E0E0E0"/> <!-- 分割线颜色 -->
<size android:height="1dp"/> <!-- 分割线高度 -->
</shape>
(3)添加分割线到 RecyclerView
java
运行
// 添加分割线
recyclerView.addItemDecoration(new DividerItemDecoration(this));
三、RecyclerView 完整使用流程(Activity 中)
java
运行
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private MyAdapter mAdapter;
private List<String> mDataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 1. 初始化控件
recyclerView = findViewById(R.id.recyclerView);
// 2. 初始化数据源
mDataList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
mDataList.add("测试Item " + (i + 1));
}
// 3. 设置LayoutManager
recyclerView.setLayoutManager(new LinearLayoutManager(this));
// 4. 设置分割线(可选)
recyclerView.addItemDecoration(new DividerItemDecoration(this));
// 5. 设置Adapter
mAdapter = new MyAdapter(this, mDataList);
recyclerView.setAdapter(mAdapter);
// 6. 可选:设置Item动画(默认已有基础动画)
recyclerView.setItemAnimator(new DefaultItemAnimator());
}
}
四、高级用法与注意事项
1. 局部刷新优化
避免使用 notifyDataSetChanged(),改用精准刷新:
java
运行
// 添加一条数据
mDataList.add("新Item");
mAdapter.notifyItemInserted(mDataList.size() - 1);
// 删除一条数据
mDataList.remove(0);
mAdapter.notifyItemRemoved(0);
// 更新一条数据
mDataList.set(1, "更新后的文本");
mAdapter.notifyItemChanged(1);
2. 滑动监听
监听 RecyclerView 滑动状态(如加载更多):
java
运行
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// dy > 0 表示向上滑动
LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
int lastVisibleItemPosition = manager.findLastVisibleItemPosition();
int totalItemCount = manager.getItemCount();
// 滑动到最后一项,触发加载更多
if (lastVisibleItemPosition == totalItemCount - 1 && dy > 0) {
// 加载更多逻辑
}
}
});
3. 性能优化总结
- 减少
onBindViewHolder()耗时操作; - 复用 ViewHolder(避免重复创建);
- 图片加载使用 Glide/Picasso 等库(支持缓存 + 异步加载);
- 关闭过度绘制(开发者选项),优化 Item 布局;
- 大数据量时使用分页加载,避免一次性加载所有数据。