一、项目概览
1.项目介绍
本项目是一个仿今日头条(HeadLine)的Android新闻列表应用,主要展示了移动端新闻资讯类App的核心列表展示功能。
1.1 项目概述
项目名称:HeadLine
包名:cn.edu.headline
核心功能:使用 RecyclerView 展示新闻列表,支持多布局切换
技术栈:Android SDK + RecyclerView + Material Design
1.2 功能特点
a.支持两种新闻列表布局(单图布局和三图布局)
b.置顶新闻特殊处理
c.适配器模式实现多视图类型
d.LinearLayoutManager线性布局管理
二、布局资源详解部分
2.布局资源详解
本项目包含以下4个核心布局文件,每个布局文件都有其特定的用途和设计考量。
2.1 主布局文件 - activity_main.xml
主布局采用垂直LinearLayout结构,从上到下依次为:
a.顶部标题栏(include引入)
b.频道标签栏
c.RecyclerView列表区域 关键代码结构:
<LinearLayout
android:orientation="vertical">
<include layout="@layout/title_bar" /> <!-- 标题栏 -->
<LinearLayout> <!-- 频道栏 -->
<TextView android:text="推荐" />
<TextView android:text="抗疫" />
<!-- 更多频道... -->
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_list" /> <!-- 列表容器 -->
</LinearLayout>
2.2 标题栏布局 - title_bar.xml
红色主题标题栏,包含:
- 红色背景(#d33d3c)
- 应用名称
- 搜索输入框
2.3 单图列表项 - list_item_one.xml
用于置顶新闻或单图新闻,采用RelativeLayout实现左图右文布局。
2.4 三图列表项 - list_item_two.xml
用于三图新闻,三个ImageView并排显示。
三、RecyclerView使用详解部分(核心重点)
3.RecyclerView使用详解
RecyclerView是Android中最强大的列表 控件 ,本项目展示了其核心用法。
3.1 RecyclerView的基本配置
3.1.1 在布局中添加RecyclerView
在 activity_main.xml 中:
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
3.1.2 在Activity中初始化
在 MainActivity.java 中:
// 1. 获取RecyclerView实例
mRecyclerView = findViewById(R.id.rv_list);
// 2. 设置布局管理器(必须)
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
// 3. 设置适配器(必须)
mAdapter = new NewsAdapter(MainActivity.this, NewsList);
mRecyclerView.setAdapter(mAdapter);
3.2 RecyclerView.Adapter核心方法
public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
// 1. 创建ViewHolder
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// 根据viewType加载不同的布局
if (viewType == 1) {
View view = LayoutInflater.from(mContext).inflate(R.layout.list_item_one, parent, false);
return new MyViewHolder1(view);
} else {
View view = LayoutInflater.from(mContext).inflate(R.layout.list_item_two, parent, false);
return new MyViewHolder2(view);
}
}
// 2. 绑定数据到ViewHolder
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
NewsBean bean = NewsList.get(position);
// 根据不同类型绑定数据...
}
// 3. 返回数据总数
@Override
public int getItemCount() {
return NewsList.size();
}
// 4. 【关键】判断item类型,实现多布局
@Override
public int getItemViewType(int position) {
return NewsList.get(position).getType();
}
}
3.3 ViewHolder模式
// ViewHolder1:单图类型
class MyViewHolder1 extends RecyclerView.ViewHolder {
ImageView iv_top, iv_img; // 置顶图标、单图
TextView title, name, comment, time;
public MyViewHolder1(View view) {
super(view);
// 绑定控件
iv_top = view.findViewById(R.id.iv_top);
iv_img = view.findViewById(R.id.iv_img);
title = view.findViewById(R.id.tv_title);
// ...
}
}
// ViewHolder2:三图类型
class MyViewHolder2 extends RecyclerView.ViewHolder {
ImageView iv_img1, iv_img2, iv_img3; // 三张图片
TextView title, name, comment, time;
public MyViewHolder2(View view) {
super(view);
iv_img1 = view.findViewById(R.id.iv_img1);
iv_img2 = view.findViewById(R.id.iv_img2);
iv_img3 = view.findViewById(R.id.iv_img3);
// ...
}
}
运行结果
四、数据模型部分
4.数据模型- NewsBean
NewsBean是新闻数据的实体类,封装了新闻的所有属性。
public class NewsBean {
private int id; // 新闻ID
private String title; // 新闻标题
private List<Integer> imgList; // 新闻图片列表
private String name; // 来源名称
private String comment; // 评论数
private String time; // 发布时间
private int type; // 新闻类型(1=单图,2=三图)
// Getter和Setter方法...
public int getType() { return type; }
public void setType(int type) { this.type = type; }
// ... 其他getter/setter
}
4.1 数据类型的设计考量
4.2 MainActivity 中的数据初始化
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 2: // 三图类型
List<Integer> imgList2 = new ArrayList<>();
imgList2.add(icons2[i - 2]);
imgList2.add(icons2[i - 1]);
imgList2.add(icons2[i]);
bean.setImgList(imgList2);
break;
// ...
}
NewsList.add(bean);
}
}
样式与资源部分
5.样式与资源文件
5.1 颜色资源- colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
<color name="light_gray_color">#eeeeee</color>
<color name="gray_color">#828282</color>
</resources>
5.2 样式定义 - styles.xml
频道标签样式 tvStyle
<style name="tvStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">match_parent</item>
<item name="android:padding">10dp</item>
<item name="android:gravity">center</item>
<item name="android:textSize">15sp</item>
</style>
信息文字样式 tvInfo
<style name="tvInfo">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginLeft">8dp</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">@color/gray_color</item>
</style>
图片样式 ivImg
<style name="ivImg">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">90dp</item>
<item name="android:layout_weight">1</item>
</style>
5.3 主题配置 - AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.NoActionBar">
<!-- NoActionBar主题隐藏系统标题栏 -->
</application>
六、关键控件使用总结
6.关键控件使用总结
6.1 RecyclerView控件使用流程
布局XML → findViewById获取实例 → 设置LayoutManager → 设置Adapter
6.2 适配器开发三步曲
| 步骤 | 方法 | 作用 |
|------|------|------|
| 1 | onCreateViewHolder() | 创建ViewHolder,加载布局 |
| 2 | onBindViewHolder() | 绑定数据到控件 |
| 3 | getItemCount() | 返回数据总数 |
6.3 多布局实现要点
1. 重写getItemViewType()方法,根据position返回不同类型
2. 在onCreateViewHolder()中根据viewType加载不同布局
3. 在onBindViewHolder()中根据holder类型分别处理
6.4 ViewHolder优化
a.所有控件在构造函数中提前findViewById
b.避免在onBindViewHolder中重复查找控件
c.使用ViewHolder模式大幅提升列表滚动性能