Android 列表控件实战:从 ListView 到 RecyclerView,仿今日头条 HeadLine 项目全解析

开篇引言

作为 Android 开发入门的核心知识点,列表控件是构建信息流、商品列表、新闻类 App 的基础。本文基于 HeadLine 仿今日头条项目,结合 ListViewRecyclerView 两个经典列表控件,从项目结构、布局资源、控件使用、适配器实现、核心原理等维度,做超详细的全流程拆解,同时配套完整代码、运行截图、原理分析,帮你彻底搞懂 Android 列表开发的核心逻辑.

目录

  • 项目总览与开发环境

  • 三大项目结构与运行效果

  • 布局资源全解析(所有 XML 布局逐行详解)

  • 核心控件详解(ListView/RecyclerView/TextView/ImageView)

  • ListView 购物商城项目全解析(代码 + 原理 + 复用机制)

  • RecyclerView 动物列表项目全解析(代码 + 原理 + 适配器)

  • HeadLine 仿今日头条项目全解析(多类型 RecyclerView 实战)

  • ListView 与 RecyclerView 核心对比

  • 知识点总结

1. 项目总览与开发环境

1.1 项目背景

本次项目基于 Android 开发经典 Chapter03 三个实战项目,完整覆盖 Android 列表控件的核心知识点:

  • ListView 购物商城项目:传统列表控件入门,掌握 BaseAdapter 与 ViewHolder 复用
  • RecyclerView 动物列表项目:现代列表控件基础,掌握 RecyclerView 核心流程
  • HeadLine 仿今日头条项目:多类型 RecyclerView 进阶,实现复杂信息流

三个项目层层递进,从基础到进阶,完整掌握 Android 列表开发的核心技能。

1.2 开发环境

  • 开发工具:Android Studio
  • 开发语言:Java
  • 最低适配版本:Android 5.0(API 21)
  • 核心依赖:android.support.v7 兼容包
  • 布局类型:LinearLayout、RelativeLayout、include 布局复用

1.3 项目目录结构

复制代码
项目目录结构

2. 三大项目结构与运行效果

2.1 ListView 购物商城项目

2.1.1 项目功能

实现简单购物商城列表,展示 6 个商品条目,每个条目包含:商品图片、商品名称、商品价格,顶部橙色标题栏。

2.1.2 运行效果截图

截图说明:顶部橙色 "购物商城" 标题栏,下方 ListView 展示 6 个商品,左图右文,价格橙色高亮,符合 UI 设计。

2.2 RecyclerView 动物列表项目

2.2.1 项目功能

实现动物信息列表,展示 5 个动物条目,每个条目包含:动物图片、动物名称、动物介绍,顶部绿色标题栏。

2.2.2 运行效果截图

截图说明:顶部绿色 "RecyclerView" 标题栏,下方 RecyclerView 展示 5 个动物,左图右文,名称橙色高亮,介绍灰色省略,符合信息流样式。

2.3 HeadLine 仿今日头条项目

2.3.1 项目功能

实现仿今日头条信息流,包含顶部标题栏、横向频道导航、多类型新闻列表(置顶 / 单图 / 三图新闻),是三个项目中最复杂的实战项目。

2.3.2 运行效果截图

截图说明:顶部 "仿今日头条" 标题栏 + 搜索框,下方横向频道标签(推荐 / 抗疫 / 小视频等),再下方 RecyclerView 展示多类型新闻列表,完全还原今日头条核心界面。


3. 布局资源全解析(所有 XML 布局逐行详解)

Android 布局资源是 UI 开发的核心,本部分完整解析三个项目中所有布局文件的作用、属性与使用逻辑。

3.1 ListView 项目布局

3.1.1 activity_main.xml(主界面布局)

完整代码
ini 复制代码
<?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">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:text="购物商城"
        android:textSize="18sp"
        android:textColor="#FFFFFF"
        android:background="#FF8F03"
        android:gravity="center"/>
    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />
</LinearLayout>
逐行解析
  1. 根布局 LinearLayout :垂直方向排列,match_parent 铺满屏幕,作为主界面根容器。

  2. 标题栏 TextView

    • layout_height="45dp":固定高度 45dp,适配标题栏尺寸
    • background="#FF8F03":橙色背景,与价格颜色统一
    • textColor="#FFFFFF":白色文字,提升可读性
    • gravity="center":文字居中,符合标题栏设计
  3. ListView 控件

    • android:id="@+id/lv":Java 代码中通过 ID 绑定控件
    • layout_width="match_parent":宽度铺满屏幕
    • layout_height="wrap_content":高度自适应列表内容

3.1.2 list_item.xml(列表 Item 布局)

完整代码
ini 复制代码
<?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:padding="16dp">
    <ImageView
        android:id="@+id/iv"
        android:layout_width="120dp"
        android:layout_height="90dp"
        android:layout_centerVertical="true"/>
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@+id/iv"
        android:layout_centerVertical="true">
        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="桌子"
            android:textSize="20sp"
            android:textColor="#000000" />
        <TextView
            android:id="@+id/tv_price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="价格:"
            android:textSize="20sp"
            android:layout_marginTop="10dp"
            android:layout_below="@+id/title"
            android:textColor="#FF8F03" />
        <TextView
            android:id="@+id/price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1000"
            android:textSize="20sp"
            android:layout_below="@+id/title"
            android:layout_toRightOf="@+id/tv_price"
            android:textColor="#FF8F03"
            android:layout_marginTop="10dp"/>
    </RelativeLayout>
</RelativeLayout>
逐行解析
  1. 根布局 RelativeLayout :支持相对定位,实现左图右文的灵活布局,padding="16dp" 避免内容贴边。

  2. 商品图片 ImageView

    • layout_width="120dp"/layout_height="90dp":固定图片尺寸,统一列表样式
    • layout_centerVertical="true":图片垂直居中,与文字对齐
  3. 内部 RelativeLayout :放置在图片右侧(layout_toRightOf="@+id/iv"),垂直居中,承载文字信息。

  4. 商品名称 TextView:黑色 20sp 字体,作为 Item 标题,突出显示。

  5. 价格标签与数值

    • tv_price:静态 "价格:" 文字,橙色 20sp 字体,位于标题下方
    • price:动态价格数值,橙色 20sp 字体,位于 "价格:" 右侧,实现价格高亮

3.2 RecyclerView 项目布局

3.2.1 activity_main.xml(主界面布局)

完整代码
ini 复制代码
<?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/id_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>
</RelativeLayout>
逐行解析
  1. 根布局 RelativeLayout:简单容器,承载 RecyclerView 控件。

  2. RecyclerView 控件

    • android:id="@+id/id_recyclerview":Java 代码绑定 ID
    • android.support.v7.widget.RecyclerView:兼容包 RecyclerView 控件,适配低版本系统
    • match_parent 铺满屏幕,作为列表容器

3.2.2 recycler_item.xml(列表 Item 布局)

完整代码
ini 复制代码
<?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:padding="16dp"
    android:gravity="center"
    android:orientation="horizontal">
    <ImageView
        android:id="@+id/iv"
        android:layout_width="120dp"
        android:layout_height="90dp"
        android:src="@drawable/siberiankusky"/>
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="5dp">
        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:textColor="#FF8F03"
            android:text="哈士奇"/>
        <TextView
            android:id="@+id/introduce"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:layout_marginTop="10dp"
            android:layout_below="@+id/name"
            android:textColor="#FF716C6D"
            android:maxLines="2"
            android:ellipsize="end"
            android:text="西伯利亚雪橇犬,常见别名哈士奇,昵称为二哈。"/>
    </RelativeLayout>
</LinearLayout>
逐行解析
  1. 根布局 LinearLayout :水平方向排列,padding="16dp" 内边距,gravity="center" 垂直居中,统一 Item 样式。

  2. 动物图片 ImageView :固定 120dp×90dp 尺寸,src 设置默认图片。

  3. 内部 RelativeLayout:图片右侧,承载文字信息。

  4. 动物名称 TextView:橙色 20sp 字体,突出显示,作为 Item 标题。

  5. 动物介绍 TextView

    • textColor="#FF716C6D":灰色字体,弱化显示
    • maxLines="2":最多显示 2 行
    • ellipsize="end":超出内容用省略号结尾,符合信息流设计

3.3 HeadLine 项目布局

3.3.1 activity_main.xml(主界面布局)

完整代码
ini 复制代码
<?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:background="@color/light_gray_color"
    android:orientation="vertical">
    <include layout="@layout/title_bar" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@android:color/white"
        android:orientation="horizontal">
        <TextView
            style="@style/tvStyle"
            android:text="推荐"
            android:textColor="@android:color/holo_red_dark" />
        <TextView
            style="@style/tvStyle"
            android:text="抗疫"
            android:textColor="@color/gray_color" />
        <TextView
            style="@style/tvStyle"
            android:text="小视频"
            android:textColor="@color/gray_color" />
        <TextView
            style="@style/tvStyle"
            android:text="北京"
            android:textColor="@color/gray_color" />
        <TextView
            style="@style/tvStyle"
            android:text="视频"
            android:textColor="@color/gray_color" />
        <TextView
            style="@style/tvStyle"
            android:text="热点"
            android:textColor="@color/gray_color" />
        <TextView
            style="@style/tvStyle"
            android:text="娱乐"
            android:textColor="@color/gray_color" />
    </LinearLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#eeeeee" />
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
逐行解析
  1. 根布局 LinearLayout:垂直排列,浅灰色背景,作为主界面容器。

  2. include 标签 :引入 title_bar.xml 标题栏布局,实现布局复用,减少代码冗余。

  3. 横向频道导航 LinearLayout

    • 白色背景,固定 40dp 高度,水平排列多个 TextView 频道标签
    • "推荐" 标签红色高亮(选中状态),其他标签灰色(未选中状态)
    • style="@style/tvStyle":统一标签样式,提升可维护性
  4. 分割线 View:1dp 高浅灰色线,分隔导航栏与新闻列表,优化视觉效果

  5. RecyclerView 控件:铺满剩余屏幕,承载多类型新闻列表,是项目核心控件

3.3.2 title_bar.xml(标题栏布局)

核心作用

复用布局,包含 "仿今日头条" 标题、搜索框,被 activity_main.xml 引入,实现标题栏复用。

3.3.3 list_item_one.xml(单图 / 置顶 Item 布局)

核心作用

单图新闻 / 置顶新闻的 Item 布局,包含置顶标识、新闻标题、单张图片、用户名、评论数、发布时间。

3.3.4 list_item_two.xml(三图 Item 布局)

核心作用

三图新闻的 Item 布局,包含新闻标题、三张横排图片、用户名、评论数、发布时间,是今日头条最常见的卡片样式。

4. 核心控件详解

本部分详细解析三个项目中所有核心控件的作用、属性与使用方法。

4.1 ListView(传统列表控件)

4.1.1 控件作用

ListView 是 Android 早期经典列表控件,用于展示大量垂直滚动的数据列表,通过 Adapter 连接数据与视图,是 Android 列表开发的入门控件。

4.1.2 核心属性

属性 作用
android:id 控件唯一标识,Java 代码中通过 findViewById 绑定
android:layout_width 控件宽度,match_parent 铺满父布局
android:layout_height 控件高度,wrap_content 自适应内容
android:divider 列表分割线颜色
android:dividerHeight 列表分割线高度

4.1.3 项目中使用流程

  1. XML 布局中添加 ListView 控件
  2. Java 代码中通过 findViewById 初始化控件
  3. 创建自定义 BaseAdapter 适配器
  4. 调用 setAdapter 方法绑定适配器,完成数据展示

4.2 RecyclerView(现代列表控件)

4.2.1 控件作用

RecyclerView 是 Android 官方推荐的现代列表控件,替代 ListView,支持多类型 Item、灵活布局、高性能复用,是 Android 列表开发的标准控件。

4.2.2 核心优势

  • 强制使用 ViewHolder 模式,性能极致优化
  • 支持多种布局管理器(线性 / 网格 / 瀑布流)
  • 支持 Item 动画、分割线、多类型布局
  • 复用机制完善,列表滑动流畅

4.2.3 核心组成

  • RecyclerView 控件:列表容器
  • LayoutManager:布局管理器,控制 Item 排列方式
  • Adapter:适配器,连接数据与视图
  • ViewHolder:缓存控件,实现视图复用
  • ItemDecoration:列表分割线
  • ItemAnimator:Item 动画

4.2.4 项目中使用流程

  1. XML 布局中添加 RecyclerView 控件
  2. Java 代码中初始化控件
  3. 设置 LayoutManager(如 LinearLayoutManager 垂直布局)
  4. 创建自定义 RecyclerView.Adapter 适配器
  5. 调用 setAdapter 方法绑定适配器,完成数据展示

4.3 TextView(文本控件)

4.3.1 控件作用

用于显示文本内容,是 Android 最基础的控件之一,广泛用于标题、价格、介绍、标签等文本展示。

4.3.2 核心属性

属性 作用
android:text 显示的文本内容
android:textSize 文本大小(单位 sp)
android:textColor 文本颜色(十六进制色值)
android:maxLines 最大显示行数
android:ellipsize 超出内容省略方式(end 结尾省略)
android:gravity 文本对齐方式
android:layout_below 相对布局属性,位于某控件下方
android:layout_toRightOf 相对布局属性,位于某控件右侧

4.4 ImageView(图片控件)

4.4.1 控件作用

用于显示图片资源,用于商品图片、动物图片、新闻图片等视觉展示。

4.4.2 核心属性

属性 作用
android:src / android:background 图片资源 ID
android:layout_width / android:layout_height 控件尺寸
android:scaleType 图片缩放模式(centerCrop 按比例裁剪)
android:layout_centerVertical 相对布局属性,垂直居中

5. ListView 购物商城项目全解析

5.1 项目核心代码(MainActivity.java)

完整代码

ini 复制代码
package cn.edu.listview;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {
    private ListView mListView;
    //商品名称与价格数据集合
    private String[] titles = {"桌子", "苹果", "蛋糕", "线衣", "猕猴桃", "围巾"};
    private String[] prices = {"1800元", "10元/kg", "300元", "350元", "10元/kg", "280元"};
    //图片数据集合
    private int[] icons = {R.drawable.table, R.drawable.apple, R.drawable.cake,
            R.drawable.wireclothes, R.drawable.kiwifruit, R.drawable.scarf};

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView = findViewById(R.id.lv); //初始化ListView控件
        MyBaseAdapter mAdapter = new MyBaseAdapter(); //创建一个Adapter的实例
        mListView.setAdapter(mAdapter);                  //设置Adapter
    }

    class MyBaseAdapter extends BaseAdapter {
        @Override
        public int getCount() {   //获取条目的总数
            return titles.length; //返回条目的总数
        }

        @Override
        public Object getItem(int position) {
            return titles[position]; //返回条目的数据对象
        }

        @Override
        public long getItemId(int position) {
            return position; //返回条目的Id
        }
        //获取条目的视图
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                //将list_item.xml文件找出来并转换成View对象
                convertView = View.inflate(MainActivity.this, R.layout.list_item, null);
                //找到list_item.xml中创建的TextView
                holder = new ViewHolder();
                holder.title =  convertView.findViewById(R.id.title);
                holder.price = convertView.findViewById(R.id.price);
                holder.iv = convertView.findViewById(R.id.iv);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.title.setText(titles[position]);
            holder.price.setText(prices[position]);
            holder.iv.setBackgroundResource(icons[position]);
            return convertView;
        }
        class ViewHolder {
            TextView title, price;
            ImageView iv;
        }
    }
}

核心方法解析

5.1.1 MyBaseAdapter 自定义适配器

继承 BaseAdapter,是 ListView 的核心,负责连接数据与视图,实现 4 个核心方法:

  1. getCount() :返回列表总条数(titles.length,6 条)
  2. getItem() :返回对应位置的数据对象
  3. getItemId() :返回对应位置的 ID(直接返回 position)
  4. getView()最核心方法,加载 Item 布局、绑定数据、实现视图复用
5.1.2 getView() 复用逻辑(ViewHolder 模式)

ListView 性能优化的核心是 ViewHolder 模式,执行流程如下:

  1. 判断 convertView 是否为 null:convertView 是 ListView 回收的滑出屏幕的 Item 视图

    • 为 null:第一次加载 Item,需要 inflate 布局、创建 ViewHolder 缓存控件
    • 不为 null:直接复用 convertView,取出缓存的 ViewHolder
  2. View.inflate:加载 list_item.xml 布局,生成 Item 视图

  3. ViewHolder 缓存控件:通过 findViewById 找到 Item 中的所有控件,存入 ViewHolder

  4. setTag():将 ViewHolder 绑定到 convertView,复用的时候直接取出

  5. 数据绑定:给 ViewHolder 中的控件设置对应位置的数据

  6. 返回 convertView,显示在 ListView 中

5.1.3 ViewHolder 内部类

作用:缓存 Item 中的控件,避免每次 getView() 都重复执行 findViewById,大幅提升列表性能,是 ListView 开发的标准写法。

6. RecyclerView 动物列表项目全解析

6.1 项目核心代码(MainActivity.java)

完整代码

scala 复制代码
package cn.edu.recyclerview;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private HomeAdapter mAdapter;
    private String[] names = {"小猫", "哈士奇", "小黄鸭", "小鹿", "老虎"};
    private int[] icons = {R.drawable.cat, R.drawable.siberianhusky,
            R.drawable.yellowduck, R.drawable.fawn, R.drawable.tiger};
    private String[] introduces = {
            "猫,属于猫科动物,分家猫、野猫,是全世界家庭中较为广泛的宠物。",
            "西伯利亚雪橇犬,常见别名哈士奇,昵称为二哈。",
            "鸭的体型相对较小,颈短,一些属的嘴要大些。腿位于身体后方,因而步态蹒跚。",
            "鹿科是哺乳纲偶蹄目下的一科动物。体型大小不等,为有角的反刍类。",
            "虎,大型猫科动物;毛色浅黄或棕黄色,满有黑色横纹;头圆、耳短,耳背面黑色,中央有一白斑甚显著;四肢健壮有力;尾粗长,具黑色环纹,尾端黑色。"
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRecyclerView = findViewById(R.id.id_recyclerview);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new HomeAdapter();
        mRecyclerView.setAdapter(mAdapter);
    }
    class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> {
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            MyViewHolder holder = new MyViewHolder(LayoutInflater.from(MainActivity.this).inflate(
                    R.layout.recycler_item, parent, false));
            return holder;
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            holder.name.setText(names[position]);
            holder.iv.setImageResource(icons[position]);
            holder.introduce.setText(introduces[position]);
        }
        @Override
        public int getItemCount() {
            return names.length;
        }
        class MyViewHolder extends RecyclerView.ViewHolder {
            TextView name;
            ImageView iv;
            TextView introduce;
            public MyViewHolder(View view) {
                super(view);
                name = view.findViewById(R.id.name);
                iv = view.findViewById(R.id.iv);
                introduce = view.findViewById(R.id.introduce);
            }
        }
    }
}

核心方法解析

6.1.1 HomeAdapter 自定义适配器

继承 RecyclerView.Adapter<HomeAdapter.MyViewHolder>,实现 3 个核心方法:

  1. onCreateViewHolder() :创建 ViewHolder,加载 Item 布局 recycler_item.xml
  2. onBindViewHolder() :绑定数据,给 ViewHolder 中的控件设置对应位置的数据
  3. getItemCount() :返回列表总条数(names.length,5 条)
6.1.2 MyViewHolder 内部类

强制继承 RecyclerView.ViewHolder,在构造方法中通过 findViewById 缓存 Item 中的控件,是 RecyclerView 强制要求的,从根本上避免了 ListView 中忘记使用 ViewHolder 的性能问题。

6.1.3 LinearLayoutManager 布局管理器

设置 new LinearLayoutManager(this),实现垂直滚动的线性布局,是 RecyclerView 最常用的布局管理器,还支持 GridLayoutManager(网格布局)、StaggeredGridLayoutManager(瀑布流布局)。

7. HeadLine 仿今日头条项目全解析

7.1 项目核心代码(MainActivity.java)

完整代码

ini 复制代码
package cn.edu.headline;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private String[] titles = {"各地餐企齐行动,杜绝餐饮浪费",
            "花菜有人焯水,有人直接炒,都错了,看饭店大厨如何做",
            "睡觉时,双脚突然蹬一下,有踩空感,像从高楼坠落,是咋回事?",
            "实拍外卖小哥砸开小吃店的卷帘门救火,灭火后淡定继续送外卖",
            "还没成熟就被迫提前采摘,8毛一斤却没人要,果农无奈:不摘不行",
            "大会、大展、大赛一起来,北京电竞"好嗨哟""};
    private String[] names = {"央视新闻客户端", "味美食记", "民富康健康", "生活小记",
            "禾木报告", "燕鸣"};
    private String[] comments = {"9884评", "18评", "78评", "678评", "189评",
            "304评"};
    private String[] times = {"6小时前", "刚刚", "1小时前", "2小时前", "3小时前",
            "4个小时前"};
    private int[] icons1 = {R.drawable.food, R.drawable.takeout,
            R.drawable.e_sports};
    private int[] icons2 = {R.drawable.sleep1, R.drawable.sleep2, R.drawable.sleep3,
            R.drawable.fruit1,R.drawable.fruit2, R.drawable.fruit3};
    //新闻类型,1表示置顶新闻或只有1张图片的新闻,2表示包含3张图片的新闻
    private int[] types = {1, 1, 2, 1, 2, 1};
    private RecyclerView mRecyclerView;
    private NewsAdapter mAdapter;
    private List<NewsBean> NewsList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setData();
        mRecyclerView = findViewById(R.id.rv_list);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new NewsAdapter(MainActivity.this, NewsList);
        mRecyclerView.setAdapter(mAdapter);
    }
    private void setData() {
        NewsList = new ArrayList<NewsBean>();
        NewsBean bean;
        for (int i = 0; i < titles.length; i++) {
            bean = new NewsBean();
            bean.setId(i + 1);
            bean.setTitle(titles[i]);
            bean.setName(names[i]);
            bean.setComment(comments[i]);
            bean.setTime(times[i]);
            bean.setType(types[i]);
            switch (i) {
                case 0: //置顶新闻的图片设置
                    List<Integer> imgList0 = new ArrayList<>();
                    bean.setImgList(imgList0);
                    break;
                case 1://设置第2个条目的图片数据
                    List<Integer> imgList1 = new ArrayList<>();
                    imgList1.add(icons1[i - 1]);
                    bean.setImgList(imgList1);
                    break;
                case 2://设置第3个条目的图片数据
                    List<Integer> imgList2 = new ArrayList<>();
                    imgList2.add(icons2[i - 2]);
                    imgList2.add(icons2[i - 1]);
                    imgList2.add(icons2[i]);
                    bean.setImgList(imgList2);
                    break;
                case 3://设置第4个条目的图片数据
                    List<Integer> imgList3 = new ArrayList<>();
                    imgList3.add(icons1[i - 2]);
                    bean.setImgList(imgList3);
                    break;
                case 4://设置第5个条目的图片数据
                    List<Integer> imgList4 = new ArrayList<>();
                    imgList4.add(icons2[i - 1]);
                    imgList4.add(icons2[i]);
                    imgList4.add(icons2[i + 1]);
                    bean.setImgList(imgList4);
                    break;
                case 5://设置第6个条目的图片数据
                    List<Integer> imgList5 = new ArrayList<>();
                    imgList5.add(icons1[i - 3]);
                    bean.setImgList(imgList5);
                    break;
            }
            NewsList.add(bean);
        }
    }
}

核心逻辑解析

7.1.1 setData() 数据初始化方法

核心作用:组装多类型新闻数据,通过 types 数组标记 Item 类型(1 = 单图 / 置顶,2 = 三图),为不同 Item 设置不同的图片集合,实现多类型列表。

7.1.2 NewsAdapter 多类型适配器

核心作用:继承 RecyclerView.Adapter<RecyclerView.ViewHolder>,通过 getItemViewType() 获取 Item 类型,加载不同的 Item 布局(list_item_one.xml/list_item_two.xml),实现多类型新闻列表。

7.1.3 NewsBean 数据实体类

封装单条新闻的所有字段:idtitleimgListnamecommenttimetype,是列表数据的载体。

8. ListView 与 RecyclerView 核心对比(万字深度分析)

8.1 复用机制对比

特性 ListView RecyclerView
复用核心 convertView 手动复用 RecyclerViewPool 自动复用
ViewHolder 可选,需手动实现 强制要求,自动缓存
性能 需手动优化,易卡顿 原生优化,性能极致
缓存层级 单层缓存 多级缓存(屏幕内 / 屏幕外 / 缓存池)

8.2 布局灵活性对比

特性 ListView RecyclerView
布局方向 仅支持垂直滚动 支持垂直 / 水平滚动
布局样式 仅线性列表 支持线性 / 网格 / 瀑布流布局
多类型 Item 需手动判断类型 原生支持 getItemViewType
Item 动画 无原生支持 原生支持 ItemAnimator

8.3 适用场景对比

场景 ListView RecyclerView
简单列表 适合,代码简单 适合,性能更优
复杂多类型列表 不适合,维护成本高 适合,原生支持
高性能列表 需手动优化 原生优化,无需额外处理
瀑布流 / 网格布局 不支持 原生支持

8.4 迁移指南:从 ListView 到 RecyclerView

  1. 替换 ListView 控件为 RecyclerView 控件
  2. 替换 BaseAdapter 为 RecyclerView.Adapter
  3. 强制实现 ViewHolder 内部类
  4. 设置 LayoutManager 控制布局样式
  5. 移除 convertView 复用逻辑,由 RecyclerView 自动处理

9. 知识点总结

核心知识点

  1. 布局资源:熟练使用 LinearLayout、RelativeLayout 进行 UI 布局,掌握 include 布局复用、RelativeLayout 相对定位属性。
  2. 控件使用:掌握 ListView、RecyclerView、TextView、ImageView 的核心属性与使用方法,理解控件的作用与适用场景。
  3. Adapter 模式 :理解 BaseAdapter 与 RecyclerView.Adapter 的工作流程,掌握 getView()onCreateViewHolder()onBindViewHolder() 等核心方法。
  4. ViewHolder 复用:理解 ViewHolder 的作用,掌握 ListView 手动复用与 RecyclerView 强制复用的实现逻辑。
  5. 多类型列表 :掌握 RecyclerView 多类型 Item 的实现方法,通过 getItemViewType() 加载不同布局。
  6. 项目实战:完成三个项目的开发、运行、截图,理解从简单列表到复杂信息流的开发流程。
相关推荐
呦呼4572 小时前
Android 仿今日头条项目分析
android
Android系统攻城狮2 小时前
Android tinyalsa深度解析之pcm_params_set_max调用流程与实战(一百七十)
android·pcm·tinyalsa·android音频进阶
怀化纱厂球迷3 小时前
android车载应用动画-仿窗帘式下拉显示!Android 实现跟手裁剪动画 + RecyclerView 列表展示
android·java
木易 士心4 小时前
Android应用启动流程源码级解析
android
八宝粥大朋友5 小时前
Android sqlite3 编译及安装
android·java·sqlite
ego.iblacat5 小时前
MySQL 主从复制与读写分离
android·mysql·adb
Android系统攻城狮5 小时前
Android tinyalsa深度解析之pcm_params_get_period_size_max调用流程与实战(一百七十二)
android·pcm·tinyalsa·音频进阶
空空kkk5 小时前
MySQL 主从同步
android·数据库·mysql
weiggle5 小时前
Android View绘制流程深度解析
android