欢迎光临
我们一直在努力

鸿蒙开发实战:仿网易新闻客户端,从零搭建新闻列表与详情页

鸿蒙开发实战:仿网易新闻客户端,从零搭建新闻列表与详情页

引言

随着鸿蒙系统(HarmonyOS)的不断普及,越来越多的开发者开始关注鸿蒙应用开发。ArkUI作为鸿蒙的声明式UI框架,提供了丰富的组件和简洁的语法,让开发者能够高效构建跨设备应用。本文将带领大家通过一个完整的实战项目——仿网易新闻客户端,从零开始搭建新闻列表页和详情页,掌握ArkUI的核心用法,并实现页面间跳转与数据传递。

📦 完整项目代码已开源:为了让你能更方便地对照学习和实践,我将本项目的全部源码托管在了 Gitee 上。你可以直接克隆或下载:👉 https://gitee.com/MFliuyangs/news.git 👈

图1:新闻列表页(轮播图+新闻条目)

Snipaste_20260314_120541.jpg 图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 中打开刚克隆的项目文件夹,连接模拟器或真机,点击运行按钮即可看到效果。
  • Snipaste_20260314_120541.jpg 图3:列表页实际运行效果

    Snipaste_20260314_120559.jpg

    开发心得与优化方向

  • 声明式UI的便利:ArkUI的声明式语法让界面与状态绑定,数据变化自动更新UI,开发效率很高。
  • 组件化思维:将轮播图、列表项等拆分为独立组件,便于复用和维护。
  • 路由传参:router.pushUrl传递对象时,需确保对象可序列化(本例中INews满足要求)。
  • 结语

    通过这个仿网易新闻客户端的实战,我们学习了ArkUI中常用的Swiper、List、Navigation等组件,掌握了页面路由和数据传递的方法。希望本文能帮助鸿蒙开发者快速入门,并激发更多创意。完整代码已放在 Gitee仓库 中,欢迎 Star 和 Fork,如果你有任何问题或建议,也欢迎在评论区交流讨论!

    赞(0)
    未经允许不得转载:171主机测评 » 鸿蒙开发实战:仿网易新闻客户端,从零搭建新闻列表与详情页
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址