前言
DevEco Studio版本:4.0.0.600
WanAndroid的API链接:玩Android 开放API-玩Android - wanandroid.com
其他篇文章参考:
效果
项目页面实现
从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()
}