鸿蒙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. 小作业

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

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

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

相关推荐
bestadc8 分钟前
鸿蒙 Form Kit(卡片开发服务)
harmonyos
Bruce_Liuxiaowei9 分钟前
HarmonyOS NEXT~鸿蒙系统运维:全面解析与最佳实践
华为·harmonyos
lqj_本人19 分钟前
鸿蒙OS&UniApp 制作个性化的评分星级组件#三方框架 #Uniapp
华为·uni-app·harmonyos
白-胖-子21 分钟前
【生产实践】华为存储XSG1在RHEL 7.x/8.x上的多路径配置操作手册(生产环境)
运维·服务器·华为
__Benco27 分钟前
OpenHarmony外设驱动使用 (十三),Vibrator
人工智能·驱动开发·harmonyos
郑知鱼1 小时前
【拥抱鸿蒙】基于 Cocos Creator 的 HarmonyOS 自动构建
华为·harmonyos·鸿蒙·移动端·鸿蒙next·ohos
颜颜yan_1 小时前
【HarmonyOS5】Stage模型应用程序包结构详解
架构·系统架构·harmonyos·鸿蒙
lqj_本人3 小时前
鸿蒙OS&UniApp 开发实时天气查询应用 —— 鸿蒙生态下的跨端实践#三方框架 #Uniapp
华为·uni-app·harmonyos
lqj_本人3 小时前
鸿蒙OS&UniApp 开发的滑动图片墙组件#三方框架 #Uniapp
华为·uni-app·harmonyos