鸿蒙开发实战:仿网易新闻客户端,从零搭建新闻列表与详情页
通过这个仿网易新闻客户端的实战,我们学习了ArkUI中常用的SwiperListNavigation等组件,掌握了页面路由和数据传递的方法。希望本文能帮助鸿蒙开发者快速入门,并激发更多创意。完整代码已放在Gitee仓库中,欢迎 Star 和 Fork,如果你有任何问题或建议,也欢迎在评论区交流讨论!
鸿蒙开发实战:仿网易新闻客户端,从零搭建新闻列表与详情页
引言
随着鸿蒙系统(HarmonyOS)的不断普及,越来越多的开发者开始关注鸿蒙应用开发。ArkUI作为鸿蒙的声明式UI框架,提供了丰富的组件和简洁的语法,让开发者能够高效构建跨设备应用。本文将带领大家通过一个完整的实战项目——仿网易新闻客户端,从零开始搭建新闻列表页和详情页,掌握ArkUI的核心用法,并实现页面间跳转与数据传递。
📦 完整项目代码已开源:为了让你能更方便地对照学习和实践,我将本项目的全部源码托管在了 Gitee 上。你可以直接克隆或下载:👉 https://gitee.com/MFliuyangs/news.git 👈
图1:新闻列表页(轮播图+新闻条目)

图2:新闻详情页
项目结构
本项目包含三个核心文件:
NewsInfo.ets:定义数据模型(IBanner、INews)和模拟数据(bannerInfo、newsInfo)。NewsCase.ets:新闻列表主页,包含头部搜索栏、轮播图和新闻列表。NewsDetailCase.ets:新闻详情页,展示新闻完整内容。
数据模型与模拟数据
首先定义两个接口,分别用于轮播图项和新闻项:
// NewsInfo.ets
interface INews {
title: string;
author: string;
time: string;
area: string;
imagefirst?: string | Resource; // 可选,新闻配图
msgcount: number; // 跟帖数
content: string;
}
interface IBanner {
id: number;
image: string | Resource;
alt: string;
}
接着准备模拟数据,其中新闻内容可以复用同一段文字(实际开发中应从网络获取)。轮播图使用本地图片路径(需提前放入images目录)。
let bannerInfo: Array<IBanner> = [
{ id: 1, image: '/images/xin1.jpg', alt: 'NBA最富老板建球场,最在意的是厕所?' },
{ id: 2, image: '/images/xin2.jpg', alt: '广告:张路&杨健带你足篮彩赢不停' }
];
let newsInfo: Array<INews> = [
{
title: '日本加强与欧洲军事互动 专家:仍不放弃“亚洲版北约”构想',
author: '国际在线',
time: '2024-11-03 19:23',
imagefirst: '/images/xw1.jpg',
msgcount: 2,
area: '北京',
content: `下周美国大选对于黄金走势很关键...` // 省略详细内容
},
// ... 更多新闻
];
新闻列表主页(NewsCase.ets)
主页由上到下分为三部分:顶部操作栏、轮播图、新闻列表。
1. 顶部操作栏
使用Row横向布局,包含网易logo、搜索框和联系人按钮。搜索框通过Search组件实现,并自定义占位文本颜色和搜索图标。
Row({ space: 5 }) {
Image($r('app.media.163_logo')).width(40);
Search({ placeholder: '输入查询内容' })
.height(35)
.layoutWeight(1)
.backgroundColor(Color.White)
.placeholderColor("#ffa29f9f")
.searchIcon({ color: "#ff9d9a9a" });
Button() {
Image($r('app.media.ic_public_contacts'))
.width(25)
.fillColor(Color.White)
.aspectRatio(1);
}
.opacity(0.4)
.backgroundColor('#000000')
.padding(5);
}
.padding(5)
.backgroundColor(Color.Red)
.width('100%');
2. 轮播图(Swiper)
使用Swiper组件自动轮播图片,通过ForEach遍历bannerInfo数组动态生成。设置自动播放、间隔1秒、无限循环等属性。
Swiper(this.swiperController) {
ForEach(this.bannerInfo, (item: IBanner) => {
Image(item.image)
.width('100%')
.alt($r('app.media.xin1'));
}, (item: IBanner): string => String(item.id));
}
.autoPlay(true)
.interval(1000)
.loop(true)
.duration(1);
3. 新闻列表(List)
新闻列表使用List组件,每个列表项为ListItem,内部采用Row横向布局,左侧是标题、作者、跟帖数,右侧是缩略图。关键点:
- 标题最多显示两行,超出省略号(
maxLines(2)+textOverflow)。 - 跟帖数超过1万时显示为“X万”格式。
- 点击列表项通过
router.pushUrl跳转到详情页,并将当前新闻对象作为参数传递。
List() {
ForEach(this.newsInfo, (item: INews) => {
ListItem() {
Row({ space: 5 }) {
Column() {
Text(item.title)
.fontSize(20)
.fontWeight(600)
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis });
Row() {
Text(item.author).margin({ right: 10 }).fontColor('#999');
Text(item.msgcount < 10000 ?
String(item.msgcount) : (item.msgcount / 10000).toFixed(1) + '万')
.fontColor('#999');
Text('跟帖').fontColor('#999');
}
.padding(5)
.width('100%');
}
.height(100)
.justifyContent(FlexAlign.SpaceBetween)
.layoutWeight(1);
Image(item.imagefirst)
.width(100)
.alt($r('app.media.xin1'))
.aspectRatio(1);
}
.width('100%')
.border({ width: { bottom: 1 } })
.borderColor('#eee')
.padding(10);
}
.onClick(() => {
router.pushUrl({
url: 'pages/NewsDetailCase',
params: item
});
});
});
}
.width('100%');
新闻详情页(NewsDetailCase.ets)
详情页接收主页传递的新闻对象,并展示完整内容。
1. 页面生命周期获取参数
在onPageShow中通过router.getParams()获取参数并赋值给状态变量news。
@State news: INews = {} as INews;
onPageShow(): void {
this.news = router.getParams() as INews;
}
2. 布局结构
使用Navigation组件作为容器,设置标题模式为Mini,标题为新闻标题。顶部显示作者、时间、地区,中间显示新闻图片(如果有)和滚动内容。
Navigation() {
Column() {
// 头部作者信息
Row() {
Image($r('app.media.news_logo_img')).width(32);
Column() {
Text(this.news.author);
Text(`${this.news.time}·${this.news.area}`)
.fontSize(10)
.fontColor('#999');
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start);
}
.width('100%')
.padding(10);
// 新闻图片(如果有)
if (this.news.imagefirst) {
Image(this.news.imagefirst)
.width('95%');
}
// 新闻内容滚动区域
Scroll() {
Text(this.news.content);
}
.margin({ top: 10 })
.layoutWeight(1);
}
.height('100%')
.width('100%');
}
.titleMode(NavigationTitleMode.Mini)
.title(this.news.title);
3. 细节优化
- 评论按钮功能暂时注释,可后续扩展。
- 内容区域使用
Scroll组件,确保长内容可滚动。 - 图片路径处理:使用
$r引用资源或直接字符串路径,需确保资源存在。
运行效果与测试
🔧 快速开始
如果你想直接运行这个项目,可以按照以下步骤操作:
- 下载开发工具:访问华为开发者官网,下载并安装最新版本的 DevEco Studio。
- 配置环境:在 DevEco Studio 中设置好 HarmonyOS SDK 的路径。
- 克隆项目:打开终端,执行以下命令将项目克隆到本地:
git clone https://gitee.com/MFliuyangs/news.git - 导入并运行:在 DevEco Studio 中打开刚克隆的项目文件夹,连接模拟器或真机,点击运行按钮即可看到效果。

图3:列表页实际运行效果

开发心得与优化方向
- 声明式UI的便利:ArkUI的声明式语法让界面与状态绑定,数据变化自动更新UI,开发效率很高。
- 组件化思维:将轮播图、列表项等拆分为独立组件,便于复用和维护。
- 路由传参:
router.pushUrl传递对象时,需确保对象可序列化(本例中INews满足要求)。
结语
通过这个仿网易新闻客户端的实战,我们学习了ArkUI中常用的Swiper、List、Navigation等组件,掌握了页面路由和数据传递的方法。希望本文能帮助鸿蒙开发者快速入门,并激发更多创意。完整代码已放在 Gitee仓库 中,欢迎 Star 和 Fork,如果你有任何问题或建议,也欢迎在评论区交流讨论!
更多推荐


所有评论(0)