首页 > 其他分享 >WanAndroid(鸿蒙版)开发的第二篇

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

时间:2024-03-14 16:01:37浏览次数:28  
标签:__ index 鸿蒙 LogUtils item result import 第二篇 WanAndroid

前言

DevEco Studio版本:4.0.0.600

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

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

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

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

4、WanAndroid(鸿蒙版)开发的第四篇

5、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()
         },
         onl oadMore: () => {
            //上拉加载
            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%')
   }
}

4、页面初始化获取Banner和首页列表数据

Banner:

aboutToAppear() {
   this.getBannerData()
}

首页列表:

aboutToAppear() {
   this.getHomeListData()
}

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

标签:__,index,鸿蒙,LogUtils,item,result,import,第二篇,WanAndroid
From: https://blog.csdn.net/Abner_Crazy/article/details/136642659

相关文章

  • HarmonyOS 鸿蒙 arkts 自定义组件插槽
    HarmonyOS鸿蒙arkts中自定义组件中要传入其他组件的时候就可以使用自定义组件插槽。Container组件添加child属性后,表示该组件具备了额外添加子组件的能力,接下来在需要添加子组件的地方使用child属性做占位即可。自定义组件@ComponentexportstructContainer{@Bu......
  • 鸿蒙开发入门实战案例-菜谱列表(附源码)
    昨天分享了鸿蒙的一些基础组件和布局方式,今天直奔主题,做一个菜谱列表,先看效果:这是实际开发中非常常见的列表样式,对初学者来说可能看起来有一些复杂,没关系,我们先从最简单的列表开始,一步一步实现它。昨天说过List列表组件的基本使用方式:List(){ListItem(){T......
  • 鸿蒙应用开发-基础动画实战
    在移动互联网时代,App的使用体验非常重要,比如布局的变化、页面的切换、弹窗的显示和隐藏都要是平顺的,丝滑的,这就需要用到动画。鸿蒙提供了很多种动画的方式,今天为大家一一分享。布局更新动画尺寸、位置等的变化都属于布局更新,鸿蒙提供了属性动画和显示动画两种方式。下面通过......
  • 3.5鸿蒙
    3.5南昌鸿蒙群面自我介绍专业课程项目经历问题Java中权限机制是如何实现的?答:管理员对用户进行管理,增删查改等。(实际上答得不好,但也不懂,确实)代码方面解释的话是用了一个java比较火的框架,ruoyijava中的锁机制是如何?线程也有很多,线程会如何占用cpu?答:java里面......
  • 鸿蒙 Harmony 的跨端技术方案
    这两年要说技术上最火的关键字,我想肯定离不开“鸿蒙”两个字。不管是技术社区还是身边的开发者多多少少都在关注鸿蒙的发展趋势,特别是HarmonyOSNEXT版本将进入独立生态体系,不再兼容安卓应用,在开发者和各个企业间激起了不小的话题。HarmonyOSNEXT系统底座作为华为完全自研的......
  • 鸿蒙开发填坑记录
    1、在DevEcoStudio中点击Previewer无法预览。出现Previewfailed.xxxxxx按照网上的检查local.properties文件中nodejs.dir路径是否和node.jshome是否一致。我的是一致的,此方法对我不管用 解决办法:1、先删除项目中的entry下的.preview文件夹。2、进入File下的Invalida......
  • 鸿蒙开发游戏(四)---大鱼吃小鱼(互吃升级)
    鸿蒙开发游戏(一)---大鱼吃小鱼(界面部署)鸿蒙开发游戏(二)---大鱼吃小鱼(摇杆控制)鸿蒙开发游戏(三)---大鱼吃小鱼(放置NPC)鸿蒙开发游戏(四)---大鱼吃小鱼(互吃升级)鸿蒙开发游戏(五)---大鱼吃小鱼(添加音效)鸿蒙开发游戏(六)---大鱼吃小鱼(称霸海洋) 前言:该篇对NPC进行了升级,这里可以投入多个......
  • 了解鸿蒙系统的基本概念、特点和应用场景
    鸿蒙系统(HarmonyOS)是华为公司开发的一款分布式操作系统,旨在满足全场景智慧生活需求。它采用微内核设计,具备高安全性、高性能和可扩展性等特点。鸿蒙系统的应用场景广泛,可以应用于智能手机、平板电脑、智能穿戴设备、智能家居、智能汽车等多种终端设备。鸿蒙系统的基本概念包括......
  • 细读鸿蒙应用生态开发白皮书
    下载鸿蒙应用生态开发白皮书版本:V2.0,发布时间:2022万物互联IoT设备量级到2025将达到百亿级,万物互联IoT场景下的挑战,开发者需要支持多样化的设备、跨设备的协作,但目前不同的设备类型包含不同的传感器能力、硬件、屏幕尺寸、OS和开发语言,还有不同的交互方式,跨设备协作面临分布式开......
  • Hybird App开发,一种快速实现纯血鸿蒙App开发的理念
    2024年1月18日的开发者(HDC)大会上,就官宣了“纯血鸿蒙”操作系统即将于2024年3季度正式投产。与此同时,支付宝、京东、小红书、微博、高德地图、中国移动等在内的超百个头部应用都启动了鸿蒙原生应用开发,鸿蒙开发者日新增注册量已过万,同时众多985、211高校接连开设HarmonyOS相关课程......