HeadLine仿今日头条项目实战博客——ListView与RecyclerView全解析(含布局与控件详解)

0 阅读16分钟

前言:在移动开发中,列表展示是最常见的功能场景之一,尤其是资讯类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”,同步依赖包,等待同步完成(确保网络通畅,避免依赖下载失败)。同步完成后,项目无报错,即可开始列表控件的开发。

fadc457bd50920df81e24146d365bc17.png

项目开发完成后,核心页面预览如下(截图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)

image.png

  1. 列表项(Item)布局 每个列表项的独立布局,需根据业务需求定制(如文本、图片、按钮组合),注意根布局宽高建议设为 match_parent(避免适配问题)。 示例布局(item_list.xml):

image.png

三、ListView 核心用法

  1. 基础使用(内置适配器) Android 提供了 aseAdapter、SimpleAdapter 等内置适配器,适用于简单场景(无需自定义 Item)。 示例:aseAdapter

image.png

四、关键优化点(避免性能问题)

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>

image.png

关键属性说明

  • layout_width/layout_height:建议设为 match_parentwrap_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>

image.png Item 布局设计原则

  • 根布局高度建议设为 wrap_content(避免固定高度导致内容截断);
  • 若需点击效果,根布局添加 android:clickable="true" + android:background="?attr/selectableItemBackground"(Material Design 水波纹);
  • 减少嵌套层级(如用 ConstraintLayout 替代多层 LinearLayout),提升绘制性能。

二、RecyclerView 核心组件用法

RecyclerView 的使用依赖 4 个核心组件:LayoutManagerAdapterViewHolderItemDecoration(可选),以下逐一拆解。

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 布局;
  • 大数据量时使用分页加载,避免一次性加载所有数据。