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

前言

DevEco Studio版本:4.0.0.600

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

其他篇文章参考:

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

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

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

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

5、WanAndroid(鸿蒙版)开发的第五篇

效果

项目页面实现

从UI效果上我们知道是可滑动的tab,切换tab时内容切换,因此通过Tabs组件实现

参考链接:OpenHarmony Tabs

因为项目模块有对BaseLibrary模块的引用,在oh-package.json5添加对其引用

1、Tabs列表实现(ProjectList)

复制代码
build() {
   Tabs({
      barPosition: BarPosition.Start,
      controller: this.tabsController,
   }) {
      ForEach(this.projectListData, (item: ProjectListItemBean) => {
         TabContent() {
            TabContentLayout({ tabId: item.id, onDataFinish: () => {
               this.onDataFinish()
            } })
         }
         .padding({ left: 12, right: 12 })
         .tabBar(new SubTabBarStyle(item.name))
      }, (item: ProjectListItemBean) => item.name)
   }
   .width('100%')
   .height('100%')
   .barMode(BarMode.Scrollable)
}

2、TabContentLayout列表内容实现

复制代码
import { HttpManager, RefreshController, RefreshListView, RequestMethod } from '@app/BaseLibrary';
import LogUtils from '@app/BaseLibrary/src/main/ets/utils/LogUtils';
import { TabContentItemBean } from '../bean/TabContentItemBean';
import { TabContentBean } from '../bean/TabContentBean';
import router from '@ohos.router';

const TAG = 'TabContentLayout--- ';

@Component
export struct TabContentLayout {
   @State controller: RefreshController = new RefreshController()
   @State tabContentItemData: Array<TabContentItemBean> = [];
   @State pageNum: number = 1 //从1开始
   @State isRefresh: boolean = true
   @Prop tabId: number
   private onDataFinish: () => void //数据加载完成回调

   aboutToAppear() {
      LogUtils.info(TAG, "tabId: " + this.tabId)
      this.getTabContentData()
   }

   private getTabContentData() {
      LogUtils.info(TAG, "pageNum: " + this.pageNum)
      HttpManager.getInstance()
         .request<TabContentBean>({
            method: RequestMethod.GET,
            header: { "Content-Type": "application/json" },
            url: `https://www.wanandroid.com/project/list/${this.pageNum}/json?cid=${this.tabId}`
         })
         .then((result: TabContentBean) => {
            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.tabContentItemData = result.data.datas
               } else {
                  this.tabContentItemData = this.tabContentItemData.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()
         })
   }

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

   @Builder
   itemLayout(item: TabContentItemBean, index: number) {
      RelativeContainer() {
         //封面
         Image(item.envelopePic)
            .alt($r('app.media.ic_default_cover'))
            .width(110)
            .height(160)
            .borderRadius(5)
            .id('imageEnvelope')
            .alignRules({
               top: { anchor: '__container__', align: VerticalAlign.Top },
               left: { anchor: '__container__', align: HorizontalAlign.Start }
            })

         //title
         //标题
         Text(item.title)
            .fontColor('#333333')
            .fontWeight(FontWeight.Bold)
            .maxLines(2)
            .textOverflow({
               overflow: TextOverflow.Ellipsis
            })
            .fontSize(18)
            .margin({ left: 15 })
            .maxLines(2)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
            .id("textTitle")
            .alignRules({
               top: { anchor: '__container__', align: VerticalAlign.Top },
               left: { anchor: 'imageEnvelope', align: HorizontalAlign.End },
               right: { anchor: '__container__', align: HorizontalAlign.End }
            })

         //描述
         Text(item.desc)
            .fontColor('#666666')
            .fontSize(16)
            .id("textDesc")
            .margin({ left: 15, top: 15 })
            .maxLines(4)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
            .alignRules({
               top: { anchor: 'textTitle', align: VerticalAlign.Bottom },
               left: { anchor: 'imageEnvelope', align: HorizontalAlign.End },
               right: { anchor: '__container__', align: HorizontalAlign.End }
            })

         //时间
         Text(item.niceDate + "  " + "作者:" + item.author)
            .fontColor('#666666')
            .fontSize(14)
            .margin({ left: 15 })
            .id("textNiceDate")
            .alignRules({
               bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
               left: { anchor: 'imageEnvelope', align: HorizontalAlign.End }
            })
      }
      .width('100%')
      .height(180)
      .padding(10)
      .margin({ left: 10, right: 10, top: 6, bottom: 6 })
      .borderRadius(10)
      .backgroundColor(Color.White)
   }
}

3、项目页面对布局引用

复制代码
import { LoadingDialog } from '@app/BaseLibrary';
import LogUtils from '@app/BaseLibrary/src/main/ets/utils/LogUtils';
import { ProjectList } from './widget/ProjectList';

@Component
export struct ProjectPage {
   @State projectLoadDataStatus: boolean = false

   aboutToAppear() {
      //弹窗控制器,显示
      this.dialogController.open()
      LogUtils.info("33333333333  ProjectPage  aboutToAppear执行了")
   }

   private dialogController = new CustomDialogController({
      builder: LoadingDialog(),
      customStyle: true,
      alignment: DialogAlignment.Center
   })

   build() {
      Column() {
         ProjectList({ onDataFinish: () => {
            this.dialogController.close()
            this.projectLoadDataStatus = true
         } })
      }
      .visibility(this.projectLoadDataStatus ? Visibility.Visible : Visibility.Hidden)
      .width('100%')
      .height('100%')
   }
}

4、页面初始化获取Tabs数据

复制代码
aboutToAppear() {
   this.getProjectListData()
}

5、根据选中的Tab获取对应Tab的内容数据

复制代码
aboutToAppear() {
   LogUtils.info(TAG, "tabId: " + this.tabId)//选中的tab的id
   this.getTabContentData()
}

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

相关推荐
youyin5 天前
HarmonyOS ArkUI 组件与自定义组件零基础:从搭页面到组件化开发
华为·harmonyos
HwJack205 天前
【HarmonyOS开发小实践】ArkTS 从 TypeScript 到方舟语言的演进
华为·harmonyos
威哥爱编程5 天前
HarmonyOS 7 星盾机密风控实战:设备风险因子端侧融合计算,可用不可见
harmonyos·arkts
威哥爱编程5 天前
HarmonyOS 7 应用快启实战:关键资源预加载进内存,冷启告别白屏
华为·harmonyos·arkts
马剑威(威哥爱编程)5 天前
【共创稿事节】HarmonyOS 7 视觉 AI 进阶实战:人脸检测 + 通用文字识别(OCR)两步接入
华为·harmonyos·arkts
HMS Core6 天前
HarmonyOS智慧多窗,让应用在任意窗口都“恰到好处”
harmonyos
梦想不只是梦与想6 天前
鸿蒙 应用发布准备工作(一)
harmonyos·鸿蒙上架·鸿蒙应用发布
马剑威(威哥爱编程)6 天前
【共创稿事节】HarmonyOS 7 文搜图实战:自然语言检索本地图片,全流程端侧闭环
华为·harmonyos
李游Leo6 天前
HarmonyOS 7 HAR + HSP 工程化实战:模块复用、包体积控制与依赖边界
harmonyos