WanAndroid(鸿蒙版)开发的第二篇

前言

DevEco Studio版本:4.0.0.600

WanAndroid的API链接:玩Android 开放API-玩Android - wanandroid.com

1、 WanAndroid(鸿蒙版)开发的第一篇

3、WanAndroid(鸿蒙版)开发的第三篇

其他一些参考点,请参考上面的WanAndroid开发第一篇

效果

首页实现

整体布局分为头部的Banner和底部的列表List,知道了整体的机构我们就来进行UI布局

1、Banner实现

参考华为官方  OpenHarmony Swiper

详细代码:

import router from '@ohos.router';
import { BannerItemBean } from '../bean/BannerItemBean';
import { HttpManager, RequestMethod } from '@app/BaseLibrary';
import LogUtils from '@app/BaseLibrary/src/main/ets/utils/LogUtils';
import { BannerBean } from '../bean/BannerBean';

const TAG = 'Banner--- ';

@Component
export struct Banner {
   @State bannerData: Array<BannerItemBean> = [];
   private swiperController: SwiperController = new SwiperController();
   @State isVisibility: boolean = true
   private onDataFinish: () => void //数据加载完成回调

   aboutToAppear() {
      this.getBannerData()
   }

   private getBannerData() {
      HttpManager.getInstance()
         .request<BannerBean>({
            method: RequestMethod.GET,
            header: { "Content-Type": "application/json" },
            url: 'https://www.wanandroid.com/banner/json', //wanAndroid的API:Banner
         })
         .then((result: BannerBean) => {
            LogUtils.info(TAG, "result: " + JSON.stringify(result))
            if (result.errorCode == 0) {
               this.isVisibility = true
               this.bannerData = result.data
            } else {
               this.isVisibility = false
            }
            this.onDataFinish()
         })
         .catch((error) => {
            LogUtils.info(TAG, "error: " + JSON.stringify(error))
            this.isVisibility = false
            this.onDataFinish()
         })
   }

   build() {
      Swiper(this.swiperController) {
         ForEach(this.bannerData, (banner: BannerItemBean) => {
            Image(banner.imagePath)
               .borderRadius(16)
               .onClick(() => {
                  router.pushUrl({
                     url: 'pages/WebPage',
                     params: {
                        title: banner.title,
                        uriLink: banner.url,
                        isShowCollect: false,
                     }
                  }, router.RouterMode.Single)
               })
         }, (banner: BannerItemBean) => banner.url)
      }
      .margin({ top: 10 })
      .autoPlay(true)
      .interval(1500)
      .visibility(this.isVisibility ? Visibility.Visible : Visibility.None)
      .width('100%')
      .height(150)
   }
}

2、List列表实现

因为是带上拉加载和下拉刷新,参考我之前文章:鸿蒙自定义刷新组件使用_harmoneyos 自定义刷新

详细代码:

import {
   BaseResponseBean,
   Constants,
   HtmlUtils,
   HttpManager,
   RefreshController,
   RefreshListView,
   RequestMethod
} from '@app/BaseLibrary';
import LogUtils from '@app/BaseLibrary/src/main/ets/utils/LogUtils';
import { HomeListItemBean } from '../bean/HomeListItemBean';
import { HomeListBean } from '../bean/HomeListBean';
import router from '@ohos.router';
import promptAction from '@ohos.promptAction';

const TAG = 'HomeList--- ';

@Component
export struct HomeList {
   @State controller: RefreshController = new RefreshController()
   @State homeListData: Array<HomeListItemBean> = [];
   @State pageNum: number = 0
   @State isRefresh: boolean = true
   private onDataFinish: () => void //数据加载完成回调
   @State userName: string = ''
   @State token_pass: string = ''
   @State listCollectState: Array<boolean> = [] //用于存储收藏状态

   aboutToAppear() {
      if (AppStorage.Has(Constants.APPSTORAGE_USERNAME)) {
         this.userName = AppStorage.Get(Constants.APPSTORAGE_USERNAME) as string
      }
      if (AppStorage.Has(Constants.APPSTORAGE_TOKEN_PASS)) {
         this.token_pass = AppStorage.Get(Constants.APPSTORAGE_TOKEN_PASS) as string
      }
      this.getHomeListData()
   }

   /**
    * 获取列表数据
    */
   private getHomeListData() {
      HttpManager.getInstance()
         .request<HomeListBean>({
            method: RequestMethod.GET,
            header: {
               "Content-Type": "application/json",
               "Cookie": `loginUserName=${this.userName}; token_pass=${this.token_pass}`
            },
            url: `https://www.wanandroid.com/article/list/${this.pageNum}/json` //wanAndroid的API:Banner
         })
         .then((result: HomeListBean) => {
            LogUtils.info(TAG, "result: " + JSON.stringify(result))
            if (this.isRefresh) {
               this.controller.finishRefresh()
            } else {
               this.controller.finishLoadMore()
            }
            if (result.errorCode == 0) {
               if (this.isRefresh) {
                  this.homeListData = result.data.datas
                  for (let i = 0; i < this.homeListData.length; i++) {
                     this.listCollectState[i] = this.homeListData[i].collect
                  }
               } else {
                  this.homeListData = this.homeListData.concat(result.data.datas)
               }
            }
            this.onDataFinish()
         })
         .catch((error) => {
            LogUtils.info(TAG, "error: " + JSON.stringify(error))
            if (this.isRefresh) {
               this.controller.finishRefresh()
            } else {
               this.controller.finishLoadMore()
            }
            this.onDataFinish()
         })
   }

   @Builder
   itemLayout(item: HomeListItemBean, index: number) {
      RelativeContainer() {
         //作者或分享人
         Text(item.author.length > 0 ? "作者:" + item.author : "分享人:" + item.shareUser)
            .fontColor('#666666')
            .fontSize(14)
            .id("textAuthor")
            .alignRules({
               top: { anchor: '__container__', align: VerticalAlign.Top },
               left: { anchor: '__container__', align: HorizontalAlign.Start }
            })

         Text(item.superChapterName + '/' + item.chapterName)
            .fontColor('#1296db')
            .fontSize(14)
            .id("textChapterName")
            .alignRules({
               top: { anchor: '__container__', align: VerticalAlign.Top },
               right: { anchor: '__container__', align: HorizontalAlign.End }
            })

         //标题
         Text(HtmlUtils.formatStr(item.title))
            .fontColor('#333333')
            .fontWeight(FontWeight.Bold)
            .maxLines(2)
            .textOverflow({
               overflow: TextOverflow.Ellipsis
            })
            .fontSize(20)
            .margin({ top: 10 })
            .id("textTitle")
            .alignRules({
               top: { anchor: 'textAuthor', align: VerticalAlign.Bottom },
               left: { anchor: '__container__', align: HorizontalAlign.Start }
            })

         //更新时间
         Text("时间:" + item.niceDate)
            .fontColor('#666666')
            .fontSize(14)
            .id("textNiceDate")
            .alignRules({
               bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
               left: { anchor: '__container__', align: HorizontalAlign.Start }
            })

         //收藏状态
         Image(this.listCollectState[index] ? $r('app.media.ic_select_collect') : $r('app.media.ic_normal_collect'))
            .width(26)
            .height(26)
            .id('imageCollect')
            .alignRules({
               bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
               right: { anchor: '__container__', align: HorizontalAlign.End }
            })
            .onClick(() => {
               this.setCollectData(item.id, index)
            })
      }
      .width('100%')
      .height(120)
      .padding(10)
      .margin({ left: 10, right: 10, top: 6, bottom: 6 })
      .borderRadius(10)
      .backgroundColor(Color.White)
   }

   build() {
      RefreshListView({
         list: this.homeListData,
         controller: this.controller,
         isEnableLog: true,
         refreshLayout: (item: HomeListItemBean, index: number): void => this.itemLayout(item, index),
         onItemClick: (item: HomeListItemBean, index: number) => {
            LogUtils.info(TAG, "点击了:index: " + index + " item: " + item)
            router.pushUrl({
               url: 'pages/WebPage',
               params: {
                  title: item.title,
                  uriLink: item.link,
                  isShowCollect: true,
                  isCollect: this.listCollectState[index]
               }
            }, router.RouterMode.Single)
         },
         onRefresh: () => {
            //下拉刷新
            this.isRefresh = true
            this.pageNum = 0
            this.getHomeListData()
         },
         onLoadMore: () => {
            //上拉加载
            this.isRefresh = false
            this.pageNum++
            this.getHomeListData()
         }
      })
   }

   /**
    * 设置收藏和取消收藏状态
    * @param id  文章id
    * @param index  数据角标
    */
   private setCollectData(id: number, index: number) {
      let collect = this.listCollectState[index]
      let urlLink = collect ? `https://www.wanandroid.com/lg/uncollect_originId/${id}/json` : `https://www.wanandroid.com/lg/collect/${id}/json` //取消收藏和收藏接口

      HttpManager.getInstance()
         .request<BaseResponseBean>({
            method: RequestMethod.POST,
            header: {
               "Content-Type": "application/json",
               "Cookie": `loginUserName=${this.userName}; token_pass=${this.token_pass}`
            },
            url: urlLink //wanAndroid的API:收藏和取消收藏
         })
         .then((result: BaseResponseBean) => {
            LogUtils.info(TAG, "收藏  result: " + JSON.stringify(result))
            if (result.errorCode == 0) {
               this.listCollectState[index] = !this.listCollectState[index]
               promptAction.showToast({ message: collect ? "取消收藏成功" : "收藏成功" })
            } else {
               promptAction.showToast({ message: result.errorMsg })
            }
         })
         .catch((error) => {
            LogUtils.info(TAG, "收藏  error: " + JSON.stringify(error))
         })
   }
}

注意点:就是在获取List数据时,通过WanAndroid的API知道要想获取收藏状态需要传入用户登录时的Cookie,但是鸿蒙没有像Android那样的Cookie处理,只能通过在登录的时候获取loginUserName和token_pass然后在请求时将这两个参数添加到请求头中,实现如下图:

这两个参数获取参考第一篇的文章。

3、将两个视图整合

详细代码:

import { Banner } from './widget/Banner';
import { HomeList } from './widget/HomeList';
import { LoadingDialog } from '@app/BaseLibrary';
import LogUtils from '@app/BaseLibrary/src/main/ets/utils/LogUtils';

@Component
export struct HomePage {
   @State bannerLoadDataStatus: boolean = false
   @State HomeListLoadDataStatus: boolean = false

   aboutToAppear() {
      //弹窗控制器,显示
      this.dialogController.open()
   }

   private dialogController = new CustomDialogController({
      builder: LoadingDialog(),
      customStyle: true,
      alignment: DialogAlignment.Center, // 可设置dialog的对齐方式,设定显示在底部或中间等,默认为底部显示
   })

   build() {
      Column() {
         Banner({ onDataFinish: () => {
            this.bannerLoadDataStatus = true
            LogUtils.info("33333333333 Banner  bannerLoadDataStatus: " + this.bannerLoadDataStatus + "  HomeListLoadDataStatus: " + this.HomeListLoadDataStatus)
            if (this.bannerLoadDataStatus && this.HomeListLoadDataStatus) {
               this.dialogController.close()
            }
         } })
         HomeList({ onDataFinish: () => {
            this.HomeListLoadDataStatus = true
            LogUtils.info("33333333333 HomeList  bannerLoadDataStatus: " + this.bannerLoadDataStatus + "  HomeListLoadDataStatus: " + this.HomeListLoadDataStatus)
            if (this.bannerLoadDataStatus && this.HomeListLoadDataStatus) {
               this.dialogController.close()
            }
         } }).flexShrink(1)
            .margin({ top: 10 })
      }
      .visibility(this.bannerLoadDataStatus && this.HomeListLoadDataStatus ? Visibility.Visible : Visibility.Hidden)
      .width('100%')
      .height('100%')
   }
}

源代码地址:WanAndroid_Harmony: WanAndroid的鸿蒙版本

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-03-14 01:30:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-14 01:30:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-14 01:30:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-14 01:30:02       20 阅读

热门阅读

  1. 【npm】 npm link软链接的使用

    2024-03-14 01:30:02       19 阅读
  2. 【MySQL 系列】MySQL 语句篇_DCL 语句

    2024-03-14 01:30:02       22 阅读
  3. 网页的用户登录功能

    2024-03-14 01:30:02       18 阅读
  4. Linux 命令汇总

    2024-03-14 01:30:02       18 阅读
  5. 【话题】人工智能迷惑行为大赏

    2024-03-14 01:30:02       23 阅读
  6. Nginx和Ribbon实现负载均衡的区别

    2024-03-14 01:30:02       22 阅读
  7. MyBatis-Plus之映射匹配

    2024-03-14 01:30:02       22 阅读
  8. 代码随想录算法训练营第16天

    2024-03-14 01:30:02       16 阅读
  9. 程序员的金三银四求职宝典

    2024-03-14 01:30:02       20 阅读