鸿蒙ArkTS-发请求第三方接口显示实时新闻列表页面

发请求展示新闻列表

鸿蒙ArkTS-发请求第三方接口显示实时新闻列表页面

1. 效果图

新闻首页:

点击某一新闻的详情页面(需要使用模拟器才能查看详情页面):

2. 代码

1. key准备

首先需求到聚合网申请一个key,网址如下:

聚合数据-个人中心

本文使用的接口API地址如下:

新闻API接口_今日头条新闻API接口_免费API数据接口_聚合数据 - 天聚地合

申请完毕后是这样的:

会有一个唯一的AppKey,这个就是我们代码中需要用到的

注意:该新闻接口虽然是免费的,但每天我们只能调用50次,你想用更多次数的话,就只能充值了

2. 新闻列表

新闻列表代码如下:

javascript 复制代码
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页面代码如下:

javascript 复制代码
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. 小作业

以上代码只能查看推荐的新闻类型,其实新闻类型有下面这些类型:

复制代码
['推荐', '国内', '国际', '娱乐', '体育', '军事', '科技', '财经', '游戏', '汽车', '健康']

请自由编写代码,实现列表页面选择指定新闻类型,就加载展示指定新闻类型内容

相关推荐
whysqwhw5 小时前
鸿蒙分布式投屏
harmonyos
whysqwhw6 小时前
鸿蒙AVSession Kit
harmonyos
whysqwhw8 小时前
鸿蒙各种生命周期
harmonyos
whysqwhw9 小时前
鸿蒙音频编码
harmonyos
whysqwhw9 小时前
鸿蒙音频解码
harmonyos
whysqwhw9 小时前
鸿蒙视频解码
harmonyos
whysqwhw9 小时前
鸿蒙视频编码
harmonyos
ajassi20009 小时前
开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器
华为·开源·harmonyos
前端世界10 小时前
在鸿蒙应用中快速接入地图功能:从配置到实战案例全解析
华为·harmonyos
江拥羡橙12 小时前
【基础-判断】HarmonyOS提供了基础的应用加固安全能力,包括混淆、加密和代码签名能力
安全·华为·typescript·harmonyos