发请求展示新闻列表
鸿蒙ArkTS-发请求第三方接口显示实时新闻列表页面
1. 效果图
新闻首页:
点击某一新闻的详情页面(需要使用模拟器才能查看详情页面):
2. 代码
1. key准备
首先需求到聚合网申请一个key,网址如下:
聚合数据-个人中心
本文使用的接口API地址如下:
新闻API接口_今日头条新闻API接口_免费API数据接口_聚合数据 - 天聚地合
申请完毕后是这样的:
会有一个唯一的AppKey,这个就是我们代码中需要用到的
注意:该新闻接口虽然是免费的,但每天我们只能调用50次,你想用更多次数的话,就只能充值了
2. 新闻列表
新闻列表代码如下:
import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction, router } from '@kit.ArkUI';
interface NewsResult {
reason: string
result: ResultJson
error_code: number
}
interface ResultJson {
stat: string
data: Array<ResultData>
page: string
pageSize: string
}
interface ResultData {
uniquekey: string
title: string
date: string
category: string
author_name: string
url: string
thumbnail_pic_s: string
is_content: string
}
/**
* Author: 波波老师(weixin:javabobo0513)
* Desc: 展示实时新闻数据列表
*/
@Entry
@Component
struct NewsPage {
@State page: number = 1; //当前页数, 最大50
@State newsType: string = 'top'; //新闻类型
//新闻数据结果
@State newsResult: NewsResult | null = null;
//新闻数据集合
@State dataList: Array<ResultData> = [];
//调用聚合网API接口的key(换成自己申请的key即可)
@State keyString: string = 'xxxxxxxxxxxxxx';
@State isRefreshing: boolean = false; //刷新标识
aboutToAppear(): void {
this.loadData();
}
//调用第三方接口获取实时新闻数据
loadData() {
//请求页数处理
if (this.page < 50) {
this.page++
} else {
this.page = 1
}
let url: string =
`http://v.juhe.cn/toutiao/index?key=${this.keyString}&type=${this.newsType}&page=${this.page}&page_size=20&is_filter=1`;
MyTools.getNewsData(url).then((res: NewsResult) => {
this.isRefreshing = false; //关闭下拉刷新效果
//打印请求结果
console.log('news = res======:', JSON.stringify(res))
this.newsResult = res;
if (this.newsResult?.error_code == 0) {
this.dataList = this.newsResult.result.data;
} else {
promptAction.showToast({ message: this.newsResult?.reason as string })
}
}).catch((error: BusinessError) => {
//发生异常时处理代码
promptAction.showToast({ message: '发生异常:' + JSON.stringify(error) })
})
}
build() {
Column() {
if (this.dataList.length > 0) {
//Refresh:可以进行页面下拉操作并显示刷新动效的容器组件
//refreshing:组件当前是否处于刷新中状态
Refresh({ refreshing: $$this.isRefreshing, promptText: '数据加载中...' }) {
List() {
ForEach(this.dataList, (item: ResultData, index) => {
ListItem() {
Column() {
Row() {
//标题
Text(item.title)
.fontSize(17)
.lineHeight(26)
.fontWeight(300)
.maxLines(2)//最多显示n行
.textOverflow({ overflow: TextOverflow.Ellipsis }) //超过n行就显示省略号
}
.padding({ top: 2, bottom: 2 })
.width('100%')
//配图
if (item.thumbnail_pic_s) {
Row() {
Image(item.thumbnail_pic_s)
.width('100%')
.height(80)
}
.justifyContent(FlexAlign.SpaceEvenly)
.width('100%')
}
Row({ space: 12 }) {
//作者
Text(item.author_name)
.fontSize(13)
.fontWeight(500)
.fontColor($r('app.color.grey_color'))
//时间
Text(item.date)
.fontSize(13)
.fontWeight(500)
.fontColor($r('app.color.grey_color'))
}
.padding({ top: 5, bottom: 5 })
.width('100%')
//分割线
Divider()
.strokeWidth(1)
.color('#fff1f1f1')
.opacity(1)//设置透明度
.width('100%')
}
.padding(12)
.width('100%')
.onClick(() => {
//跳转到新闻详情页面
router.pushUrl({
url: 'pages/Test/WebPageDetails',
params: {
url: item.url,
},
}, router.RouterMode.Single)
})
}
})
}
.alignListItem(ListItemAlign.Center)
.height('98%')
}
//进入刷新状态时触发回调
.onRefreshing(() => {
//下拉时调用接口获取最新数据
this.loadData();
})
.refreshOffset(64) //设置触发刷新的下拉偏移量
.pullToRefresh(true) //设置当下拉距离超过refreshOffset时是否能触发刷新
} else {
Row() {
Text('暂无数据')
.fontWeight(800)
.fontSize(35)
}
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
.height('100%')
.width('100%')
}
}
class MyTools {
/**
* 发请求给第三方接口获取新闻数据
*/
static getNewsData(url: string): Promise<NewsResult> {
return new Promise((resolve: Function, reject: Function) => {
let httpRequest = http.createHttp();
httpRequest.request(url, {
method: http.RequestMethod.GET,
}).then((resp: http.HttpResponse) => {
if (resp.responseCode === 200) {
console.log('news = 获取数据成功:', resp.result)
resolve(JSON.parse(resp.result.toString()))
} else {
console.log('news = 获取数据失败,error:', JSON.stringify(resp))
reject('HTTP请求获取数据失败!')
}
})
})
}
}
页面往下拉时会自动加载第二页新闻数据
3. 新闻详情页面
上面代码中WebPageDetails页面代码如下:
import router from '@ohos.router';
import webview from '@ohos.web.webview';
/**
* Author: 波波老师(weixin:javabobo0513)
* Desc: 网页详情页面
*/
@Entry
@Component
struct WebPageDetails {
controllerWeb: webview.WebviewController = new webview.WebviewController();
//接收上一个页面传来的参数 url 的值(网址)
@State url: string = (router.getParams() as Record<string, string>)['url'];
build() {
Column() {
Row({ space: 3 }) {
Text('返回')
.onClick(() => {
router.back();
})
}
.padding(10)
.width('100%')
Web({ controller: this.controllerWeb, src: this.url })
.id(String(new Date().getTime()))
.domStorageAccess(true)
}
}
}
3. 小作业
以上代码只能查看推荐的新闻类型,其实新闻类型有下面这些类型:
['推荐', '国内', '国际', '娱乐', '体育', '军事', '科技', '财经', '游戏', '汽车', '健康']
请自由编写代码,实现列表页面选择指定新闻类型,就加载展示指定新闻类型内容