前言
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: numberprivate 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 = truethis.pageNum = 0this.getTabContentData()},onLoadMore: () => {//上拉加载this.isRefresh = falsethis.pageNum++this.getTabContentData()}})}@BuilderitemLayout(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 = falseaboutToAppear() {//弹窗控制器,显示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的idthis.getTabContentData()
}
源代码地址:WanAndroid_Harmony: WanAndroid的鸿蒙版本