#星计划# 基于鸿蒙应用开发:每日新闻头条 原创

Aircreach
发布于 2023-12-25 10:35
浏览
10收藏

基于Http请求开发,每日新闻头条

环境:OpenHarmony 4.0
设备:润和大禹200开发板

1.项目预览图:

#星计划# 基于鸿蒙应用开发:每日新闻头条-鸿蒙开发者社区#星计划# 基于鸿蒙应用开发:每日新闻头条-鸿蒙开发者社区#星计划# 基于鸿蒙应用开发:每日新闻头条-鸿蒙开发者社区

2.底层架构流程图

aboutToApear=>start: aboutToApear
e=>end: Finish
getNews01=>operation: 调用getNews方法获取首页新闻
build=>operation: build() 界面渲染
scoller=>operation: 向下滑动刷新
tabs=>operation: 切换TabBar,getNews重新获取新闻
list=>operation: List点击事件跳转使用web组件加载网页

aboutToApear->getNews01->build->scoller->tabs->list->e

3.代码实现

(1) 主要界面

import http from '@ohos.net.http';
import NewItem from '../Component/NewItem';
import New from '../pojo/New';
import router from '@ohos.router';

@Entry
@Component
struct NewsPage {
  @State news: New[] = []
  @State content: string = ''
  @State flag: boolean = false
  @State types: string[] = ['生活', '明星', 'NBA', '经济', '商业', '趣闻', '游戏', '文学', '专栏']
  token: string = 'PpDpYWLcFLBIwYgu'
  type: number = 1
  page: number = 1
  startIndex: number = 0
  endIndex: number = 0
  downY: number = 0

  // 获取新闻
  async getNews(type: number, page: number) {
    let httpRequest: http.HttpRequest = http.createHttp()
    httpRequest.request('https://v2.alapi.cn/api/new/toutiao', {
      method: http.RequestMethod.POST,
      extraData: `type=${type}&page=${page}&token=${this.token}`

    }).then((res: http.HttpResponse) => {
      let code: string = JSON.parse(`${res.result}`).code
      let msg: string = JSON.parse(`${res.result}`).msg
      if (code == '200') {
        let n: New[] = JSON.parse(`${res.result}`).data
        // if (type == this.type) {
        //   this.news.concat(n)
        // }
        this.news = n
        this.flag = true
        console.log(`[Response SUCCESS] => CODE: ${code} MSG: ${msg}`)
      } else {
        this.content = '<h1 style="text-align: center;">出错了, 找不到资源</h1>'
        this.flag = true
        console.error(`[Response ERROR] => CODE: ${code}  MSG: ${msg}`)
      }
    }).catch((err: Error) => {
      this.content = '<h1 style="text-align: center;">出错了, 找不到资源</h1>'
      this.flag = true
      console.error('[Response ERROR] => CODE: ' + JSON.stringify(err))
    })
  }

  // 下拉刷新 => 获取下一页数据
  refreshNews(event: TouchEvent, index: number) {

    const refreshY = vp2px(100)
    switch(event.type) {
      case TouchType.Down:
        this.downY = event.touches[0].y
        break
      case TouchType.Move:
        if (this.startIndex == 0) {
          let offsetY = event.touches[0].y - this.downY
          if (offsetY > refreshY) {
            this.flag = false
            this.page ++
            this.getNews(index +1, this.page)
          }
        }
        break
    }
  }

  aboutToAppear() {
    this.getNews(1, 1)
  }

  build() {
    Column() {
      Text('今日头条').font({size: 22, weight: FontWeight.Bold}).width(100)
      Tabs() {
        ForEach(this.types, (item: string, index: number) => {
          TabContent() {
            if (this.flag) {
              List() {
                ForEach(this.news, (item: New, index: number) => {
                  ListItem() {
                    NewItem({ new: item })
                  }
                  .margin({top: 5})
                  .onClick(() => {
                    console.log(`EVENT_CLICK ON ${index}`)
                    router.pushUrl({
                      url: 'pages/DetailsPage',
                      params: item
                    })
                  })
                })
              }
              .width('90%')
              .height('90%')
              .onScrollIndex((start, end) => {
                this.startIndex = start
                this.endIndex = end
              })
              .onTouch((event: TouchEvent) => {
                this.refreshNews(event, index)
              })
            } else {
              LoadingProgress().width(100)
            }
          }
          .tabBar(item)
        })
      }.onChange((index: number) => {
        this.flag = false
        this.page = 1
        this.type = index + 1
        this.getNews(index + 1, 1)
      })
    }
    .backgroundImage($r('app.media.background01'))
    .backgroundImageSize({width: '100%', height: '100%'})
    .width('100%')
    .height('100%')
  }
}

(2) ListItem组件

import New from '../pojo/New'

@Preview
@Component
export default struct NewItem {

  new: New = new New('', '', '', '', '', '', '', '', '')


  build() {
    Column() {
      Text(this.new.title)
        .font({size: 20})
        .fontColor('#ff050f6d')
        .maxLines(1)
        .textOverflow({overflow: TextOverflow.Ellipsis})
        .width('100%')
      Row({space: 2}) {
        Text(this.new.digest).maxLines(3).width('80%')
        Image(this.new.imgsrc)
          .width('20%')
          //.alt($r('app.media.icon'))
      }.width('100%').margin({top: 2})
      Row({space: 5}) {
        Text(this.new.source).fontSize(12).fontColor('#ffb7b4b4')
        Text(this.new.time).fontSize(12).fontColor('#ffb7b4b4')
      }.width('95%').justifyContent(FlexAlign.End)
      Divider()
        .strokeWidth(1)
        .lineCap(LineCapStyle.Round)
        .linearGradient({direction: GradientDirection.Right, colors: [['#fff89cff', 0], ['#fff4ff8a', 0.25], ['#ff13f8f1', 0.5], ['#ffff8849', 0.75], ['#ff18a1fd', 1]]})

    }.width('100%')
  }
}         

(3) 实体类

@Observed
export default class New {
  title: string
  type: string
  digest: string
  docid: string
  pc_url: string
  m_url: string
  imgsrc: string
  source: string
  time: string

  constructor(title: string, type: string, digest: string, docid: string, pc_url: string, m_url: string, imgsrc: string, source: string, time: string) {
    this.title = title
    this.type = type
    this.digest = digest
    this.docid = docid
    this.pc_url = pc_url
    this.m_url = m_url
    this.imgsrc = imgsrc
    this.source = source
    this.time = time
  }
}
注意:该代码仅为应用开发示例,功能并不完善。如需运行:请在media目录添加background01背景图片文件,新闻Api为网易头条Api,每日限制请求200次

4.参考文献

鸿蒙应用开发指南

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2023-12-25 11:15:54修改
13
收藏 10
回复
举报
回复
    相关推荐