





























为支持开发者单独获取特定场景的页面和功能,本模板将功能完全自闭环的部分能力抽离出独立的行业组件模块,不依赖公共基础能力包,开发者可以单独集成,开箱即用,降低使用难度。
├──commons
│ ├──lib_account/src/main/ets // 账号登录模块
│ │ ├──components
│ │ │ └──AgreePrivacyBox.ets // 隐私同意勾选
│ │ ├──constants // 常量
│ │ ├──pages
│ │ │ ├──HuaweiLoginPage.ets // 华为账号登录页面
│ │ │ ├──OtherLoginPage.ets // 其他方式登录页面
│ │ │ └──ProtocolWebView.ets // 协议H5
│ │ ├──services // 服务api
│ │ ├──utils
│ │ │ ├──ErrorCodeHelper.ets // 错误码处理工具类
│ │ │ ├──HuaweiAuthUtils.ets // 华为认证工具类
│ │ │ ├──LoginSheetUtils.ets // 统一登录半模态弹窗
│ │ │ └──WXApiUtils.ets // 微信登录事件处理类
│ │ └──viewmodels // 视图模型
│ │
│ ├──lib_api/src/main/ets // 服务端api模块
│ │ ├──database // 数据库
│ │ ├──params // 请求响应参数
│ │ └──services // 服务api
│ │
│ ├──lib_common/src/main/ets // 基础模块
│ │ ├──components // 通用组件
│ │ ├──constants // 通用常量
│ │ ├──dialogs // 通用弹窗
│ │ ├──mocks // 模拟数据
│ │ ├──models // 状态观测模型
│ │ ├──types // 类型
│ │ └──utils // 通用方法
│ │
│ └──lib_widget/src/main/ets // 通用UI模块
│ └──components
│ └──NavHeaderBar.ets // 自定义标题栏
│
├──components
│ ├──aggregated_payment // 通用支付组件
│ ├──module_chart // 图表组件
│ ├──module_feedback // 意见反馈组件
│ ├──module_imagepreview // 图片预览组件
│ ├──module_player // 播放组件
│ ├──module_search // 搜索组件
│ └──module_transition // 动画组件
│
├──features
│ ├──home/src/main/ets // 首页模块
│ │ ├──pages
│ │ │ ├──CommonKnowledgeActivatePage.ets // 激活页
│ │ │ ├──CommonKnowledgeDrawPage.ets // 拉伸页
│ │ │ ├──CommonKnowledgeEquipPage.ets // 装备页
│ │ │ ├──CommonKnowledgePage.ets // 常识页面
│ │ │ ├──CommonKnowledgeStrainPage.ets // 避免受伤页
│ │ │ ├──CommonKnowledgeWarmPage.ets // 热身页
│ │ │ ├──CommonKnowledgeYogaPage.ets // 瑜伽页
│ │ │ └──HomePage.ets // 首页页面
│ │ └──viewmodels
│ │ └──CommonKnowledgePageVM.ets // 常识页面视图模块
│ ├──course/src/main/ets // 课程模块
│ │ ├──pages
│ │ │ ├──AdvancedCoursePage.ets // 进阶课程页面
│ │ │ ├──CourseDetailPage.ets // 课程详情页面
│ │ │ ├──CoursePage.ets // 课程页面
│ │ │ ├──CoursePlayer.ets // 课程视频
│ │ │ ├──CourseSearch.ets // 课程搜索
│ │ │ ├──FilterPage.ets // 课程筛选
│ │ │ └──HotCoursePage.ets // 热门课程
│ │ └──viewmodels
│ │ ├──AddDateDialog.ets // 添加日程
│ │ ├──AdvancedCoursePageVM.ets // 进阶课程视图模型
│ │ ├──Calendar.ets // 日历
│ │ ├──CoursePageVM.ets // 课程视图模型
│ │ ├──CustomDialog.ets // 自定义弹窗
│ │ └──HotCoursePageVM.ets // 热门课程视图模型
│ │
│ ├──mine/src/main/ets // 我的模块
│ │ ├──components
│ │ │ ├──CourseItemComponent.ets // 课程组件
│ │ │ ├──LeftSwipeComponent.ets // 左滑组件
│ │ │ ├──VipBenefits.ets // VIP权益
│ │ │ ├──VipOpen.ets // 开通VIP
│ │ │ ├──VipOperation.ets // VIP操作
│ │ │ └──VipPackage.ets // VIP套餐包
│ │ ├──constants // 常量
│ │ ├──model // 模型
│ │ ├──preview // 预览
│ │ ├──types // 类型
│ │ ├──utils // 工具类
│ │ ├──viewmodels // 视图模型
│ │ └──pages
│ │ ├──HistoryPage.ets // 我的足迹
│ │ ├──MarkPage.ets // 我的收藏
│ │ ├──RecordPage.ets // 运动记录
│ │ ├──VIPPage.ets // 会员页面
│ │ └──MinePage.ets // 我的页面
│ │
│ ├──plan/src/main/ets // 计划模块
│ │ ├──pages
│ │ │ ├──CoursePlanPage.ets // 课程计划详情页面
│ │ │ ├──PlanPage.ets // 计划主页
│ │ │ └──RecommendationCoursePage.ets // 推荐课程页面
│ │ └──viewmodels
│ │ └──PlanPageVM.ets // 计划视图模块
│ │
│ └──setting/src/main/ets // 设置模块
│ ├──components
│ │ ├──SettingCard.ets // 设置卡片
│ │ └──SettingSelectDialog.ets // 设置选项弹窗
│ │──pages
│ │ ├──SettingAbout.ets // 关于页面
│ │ ├──SettingH5.ets // H5页面
│ │ ├──SettingNetwork.ets // 视频播放设置页面
│ │ ├──SettingPage.ets // 设置页面
│ │ ├──SettingPersonal.ets // 编辑个人信息页面
│ │ └──SettingPrivacy.ets // 隐私设置页面
│ ├──types // 类型
│ └──viewmodels // 视图模型
│
└──products
└──phone/src/main/ets // phone模块
├──common
│ ├──AppTheme.ets // 应用主题色
│ ├──AppUtils.ets // 应用设置工具类
│ ├──Constants.ets // 业务常量
│ ├──NetworkUtils.ets // 网络工具类
│ ├──Types.ets // 数据模型
│ ├──WantUtils.ets // want工具类
│ └──WindowUtils.ets // 窗口工具类
├──components
│ └──CustomTabBar.ets // 应用底部Tab
│──pages
│ ├──AgreeDialogPage.ets // 隐私同意弹窗
│ ├──GuidePage_*.ets // 引导页面
│ ├──Index.ets // 入口页面
│ ├──IndexPage.ets // 应用主页面
│ ├──PrivacyPage.ets // 查看隐私协议页面
│ ├──SafePage.ets // 隐私同意页面
│ └──SplashPage.ets // 开屏广告页面
└──viewmodels // 视图模型
markerBuilder() {
// 是否在图表content内&&是否有数据
if (this.customUiInfo.isInbounds && this.customUiInfo.data && this.customUiInfo.y) {
Column() {
Text() {
Span(`${this.customUiInfo.data.getY()}分钟`);
}
.fontSize($r(‘sys.float.Body_M’));
}
.borderRadius(99)
.justifyContent(FlexAlign.Center)
.padding(12)
.backgroundColor(Color.White)
.shadow({
radius: 20,
offsetX: 0,
offsetY: 0,
color: ‘#33000000’,
})
.width(this.customUiInfo.width)
.height(this.customUiInfo.height)
.margin({ left: this.customUiInfo.x, top: this.customUiInfo.y })
.onAppear(() => {
const timer = setTimeout(() => {
this.customUiInfo.showUi = false;
clearTimeout(timer);
}, 2000);
})
.alignItems(HorizontalAlign.Start)
.onClick(() => {
this.customUiInfo.showUi = false;
});
}
}
async initChartSetting() {
// 显示描述
this.model.getDescription()?.setEnabled(false);
// 初始化动画时长
this.model.animateY(1000);
// 显示图例
this.model.getLegend()?.setEnabled(false);
// 设置额外偏移量
this.model.setExtraOffsets(10, 10, 10, 5);
// 绘制柱状体阴影背景
this.model.setDrawBarShadow(false);
// 柱状体上方显示数值
this.model.setDrawValueAboveBar(false);
// 为图表添加数据选择的监听器
this.model.setOnChartValueSelectedListener(this._valueSelectedListener);
// 绘制图表背景色
this.model.setDrawGridBackground(false);
// 设置左轴
const leftAxis = this.model.getAxisLeft();
if (leftAxis) {
leftAxis.setAxisMinimum(0);
leftAxis.setGridColor(ChartColor.argb(60, 0, 0, 0));
leftAxis.setTextColor(ChartColor.argb(200, 0, 0, 0));
leftAxis.setAxisLineColor(ChartColor.rgb(255, 255, 255));
leftAxis.setLabelXOffset(-10);
}
// 设置右轴不显示
this.model.getAxisRight()?.setEnabled(false);
const xAxis = this.model.getXAxis();
if (xAxis) {
xAxis.setValueFormatter(new MyAxisValueFormatter(this.chartData.month));
xAxis.setPosition(XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setAxisLineColor(ChartColor.argb(60, 0, 0, 0));
xAxis.setTextColor(ChartColor.argb(200, 0, 0, 0));
}
// 初始化图表数据
this.getChartData();
}
async getChartData() {
const month = new Date(this.chartData.month);
this.model.getXAxis()?.setValueFormatter(new MyAxisValueFormatter(this.chartData.month));
const totalDayNum = new Date(month.getFullYear(), month.getMonth() + 1, 0).getDate();
this.displayData = [];
for (let i = 1; i <= totalDayNum; i++) {
const bill = this.chartData.data.find((item) => {
const day = item.date.split(‘-‘)[2];
return Number(day) === i;
});
if (bill) {
this.displayData.push({
date: bill.date,
value: bill.value,
});
} else {
const date = dayjs().set(‘month’, month.getMonth()).set(‘date’, i);
this.displayData.push({
date: date.format(‘YYYY-MM-DD’),
value: 0,
});
}
}
await this.setData();
}
async setData() {
let dataSetList: JArrayList<IBarDataSet> = new JArrayList<IBarDataSet>();
let values: JArrayList<BarEntry> = new JArrayList<BarEntry>();
for (let i = 0; i < this.displayData.length; i++) {
values.add(new BarEntry(i + 1, this.displayData[i].value));
}
let dataSet: BarDataSet = new BarDataSet(values, ‘DataSet’);
dataSet.setColorByColor(this.initColor);
dataSet.setDrawValues(false);
dataSet.setHighLightColor(this.highlightColor);
// 显示数据格式化
dataSetList.add(dataSet);
let barData: BarData = new BarData(dataSetList);
barData.setBarWidth(0.85);
if (this.model) {
this.model.setData(barData);
}
return barData;
}
setR(orientation: number) {
window.getLastWindow(getContext(this)).then((win) => {
win.setPreferredOrientation(orientation).then(() => {
}).catch(() => {
})
}).catch(() => {
})
}
// 设置沉浸式窗口
setFullScreen(isLayoutFullScreen: boolean) {
window.getLastWindow(getContext(this)).then((win: window.Window) => {
win.setWindowLayoutFullScreen(isLayoutFullScreen).then(() => {
}).catch(() => {
})
}).catch(() => {
})
this.fullScreen(isLayoutFullScreen)
this.setComponentHeight()
}
regDisplayListener(): void {
display.on(‘foldStatusChange’, async (curFoldStatus: display.FoldStatus) => {
// 同一个状态重复触发不做处理
if (this.curFoldStatus === curFoldStatus) {
return;
}
this.curFoldStatus = curFoldStatus;
this.setComponentHeight()
})
}
setComponentHeight() {
let screenWidth = display.getDefaultDisplaySync().width
if (this.curFoldStatus === display.FoldStatus.FOLD_STATUS_FOLDED ||
this.curFoldStatus === display.FoldStatus.FOLD_STATUS_UNKNOWN) {
this.componentHeight = ‘100%’
} else {
if (this.isLayoutFullScreen) {
let height = (this.getUIContext().px2vp(screenWidth) – 32) * 9 / 16
this.componentHeight = height.toString() + ‘vp’
} else {
this.componentHeight = ‘100%’
}
}
}
async aboutToAppear() {
if (this.movieItems && this.movieItems.length > 0) {
this.playerVM.movieItemList = this.movieItems
this.playerVM.movieItem = this.playerVM.movieItemList[this.playerIndex]
}
PipManager.getInstance().init(getContext(this), this.playerVM.navId)
window.getLastWindow(getContext(this)).then((currentWindow: window.Window) => {
this.mWindow = currentWindow;
// 获取窗口属性
let properties = currentWindow.getWindowProperties();
let rect = properties.windowRect;
if (this.getUIContext().px2vp(rect.height) <= 680) {
this.windowStatusType = 5
this.playerVM.windowStatusType = this.windowStatusType
this.isLayoutFullScreen = false
this.setR(1)
this.setFullScreen(false)
}
currentWindow.on(‘windowStatusChange’, (windowStatusType) => {
this.windowStatusType = windowStatusType
this.playerVM.windowStatusType = this.windowStatusType
if (windowStatusType === 5) {
this.isLayoutFullScreen = false
this.setR(1)
this.setFullScreen(false)
}
});
})
this.isLayoutFullScreen = true
this.setR(this.isLayoutFullScreen ? 2 : 1)
this.setFullScreen(this.isLayoutFullScreen)
emitter.on(‘playerPause’, (event: emitter.EventData) => {
let isPlaying = event.data!.isPlaying as boolean
if (isPlaying) {
PipManager.getInstance().player.isResetPause = false
PipManager.getInstance().player.isPlaying = true
} else {
PipManager.getInstance().player.isResetPause = true
PipManager.getInstance().player.isPlaying = false
}
})
emitter.on(‘autoStartPip’, () => {
if (this.playerVM.autoStartEnabled) {
if (PipManager.getInstance().player.isPipOpen) {
} else {
PipManager.getInstance().startPip()
PipManager.getInstance().updatePiPControlStatus();
}
} else {
if (PipManager.getInstance().player.isPipOpen) {
} else {
PipManager.getInstance().player.isPlaying = false
}
}
})
emitter.on(‘chapterDetailBack’, () => {
if (!PipManager.getInstance().player.isPipOpen) {
// 释放AVPlayer资源
PipManager.getInstance().stopPip()
PipManager.getInstance().player.isCreate = true
PipManager.getInstance().player.release();
}
})
if (display.isFoldable()) {
this.regDisplayListener();
}
this.curFoldStatus = display.getFoldStatus()
this.setComponentHeight()
}
aboutToDisappear() {
// 释放AVPlayer资源
PipManager.getInstance().player.isCreate = true
PipManager.getInstance().player.release();
this.setR(1)
this.setFullScreen(true)
this.isLayoutFullScreen = false
}
@Builder
xComponentView() {
Column() {
XComponent({
type: XComponentType.SURFACE,
controller: PipManager.getInstance().getXComponentController()
})
.id(‘XComponent01’)
.layoutWeight(1)
.onLoad(() => {
this.surfaceId = PipManager.getInstance().getXComponentController().getXComponentSurfaceId();
// 将surfaceId设置给媒体源
PipManager.getInstance().getXComponentController().onSurfaceCreated(this.surfaceId)
PipManager.getInstance().player.init(this.courseId, this.playerVM.movieItem.movieUrl,
this.playerVM.movieItem.learnProgress)
PipManager.getInstance().player.callbackTimeUpdate = (vol: number, total: number) => {
this.callbackTimeUpdate(vol, total)
this.playerVM.movieItem.learnProgress = Math.floor(vol / total * 100)
}
})
}
.width(‘100%’)
.height(this.componentHeight)
}
在commons/lib_api/src/main/ets/params/response/AuthorResponse.ets文件中将云侧开发者自定义的数据结构转换为端侧数据结构。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。