diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/.gitignore b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..dc4e6353bf3caf74c5953d0bec81c72a3635bf33 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/.gitignore @@ -0,0 +1,9 @@ +/node_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/AppScope/app.json5 b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..32034c337146aa1f8fb90d54652cc2ac9f63fe87 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/AppScope/app.json5 @@ -0,0 +1,11 @@ +{ + "app": { + "bundleName": "cn.lavachen.sngapp", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name", + "distributedNotificationEnabled": true + } +} diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/AppScope/resources/base/element/string.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..c982473eae433e2fd2f4f85450c63f29567385a0 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "SngApp" + } + ] +} diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/AppScope/resources/base/media/app_icon.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/AppScope/resources/base/media/app_icon.png differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/README.md b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5d77d283d37ed63d4353723664c3233584ec96e1 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/README.md @@ -0,0 +1,65 @@ +#HarmonyOS ArkUI入门训练营-少年宫应用 +== + +这个APP是用arkui实现声明式的UI + +整个UI主要操作演示如下: + +![操作演示](./images/操作演示.gif) + +UI页面结构: +==== +**包含** +* logo页 +* 课程页(签到功能) +* 个人信息页(表单) +* 课程报名页 + +**各页面说明** + +logo页主要是实现文字和图片的渐变效果,然后延迟几秒跳转到课程页面(利用onappear事件) + +![logo页](./images/page_logo.png) + +课程页 + +底部tab导航实现双页面的切换,分为课程和个人页面 + +![课程页](./images/checkin.png) + +* 课程项 + + 提供课程报名 跳转 和 课程签到的功能 + 其中课程的签到功能,实现了弹出查看课程的对话,并且继续确认签到 并弹出成功的提示。这其中是实现两个对话框。难点是对各组件间状态的传递,并实现对签到状态的更新 + + ![签到页](./images/check_dialog.png) + +* 个人项 + ![个人页](./images/page_profile.png) + 使用表单常见的元素,比如文本框,日期选择,toggle切换等,其中难点是日期的选择,内置的datepicker是直接占着一块大块区域,并非弹出层,这方式对用户体验不好。于是放在dialog选择并渲染结果,是最佳方案。提交逻辑尚未实现 + ![日期选择](./images/page_datepick.png) + +报名页 + +![报名页](./images/enroll.png) + +页面主要有tabs(四个内容块,其中提供的课程数据 利用filter来分组渲染),底部的固定操作bar(类似fixed的bottom,点击报名会有pop提示),以以及中间的已选课程列表(查看已选,删除已选以及清空功能)。以上主要区域靠stack容器来堆叠。 + +点击课程 会出现选中状态,并且出现在下方的购物车,同步更新课程数量。若课程数量为零,购物车卡片会自动下降。曾考虑panel来搞,但是不能满足复杂的需求,换成自己实现。 + +课程长按会打开课程详情页面。 + +![详情页](./images/detail.png) + + + +**开发心得** + +通过这次的训练营活动和视频学习,虽然留给我练手的时间并不多(一周),但是体会到了ArkUI声明式开发简洁敏捷的特点,DevEco对ArkUI开发的友好支持,更是吸引开发者的学习开发热情,同时也提高了UI的开发效率。 + +目前我只是对ArkUI有了基本的了解和实践,对代码API的熟练和代码的封装复用性上面还需要多多积累经验,后期还要多多学习练习其他方面知识,争取在鸿蒙的应用开发中成为资深的开发者,为鸿蒙的生态丰富性贡献自己的力量。 + + + + + diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/build-profile.json5 b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..d7b1117cdb34aab2983ac65026d9e8dcc91332d1 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/build-profile.json5 @@ -0,0 +1,27 @@ +{ + "app": { + "signingConfigs": [], + "compileSdkVersion": 9, + "compatibleSdkVersion": 9, + "products": [ + { + "name": "default", + "signingConfig": "default", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/.gitignore b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..5a6ba80fa3d9498a23ae8ae7d9518f8743fa8a96 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/.gitignore @@ -0,0 +1,4 @@ +/node_modules +/.preview +/build +/.cxx \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/build-profile.json5 b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f8f03407f77914b43168aeca6bb0929efd6700b4 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/build-profile.json5 @@ -0,0 +1,13 @@ +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/hvigorfile.ts b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..80e4ec5b81689f238c34614b167a0b9e9c83e8d9 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/package-lock.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..15bc7145be1490029883067847743ea7134cf545 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "entry", + "version": "1.0.0", + "lockfileVersion": 1 +} diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/package.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/package.json new file mode 100644 index 0000000000000000000000000000000000000000..c4e988f30f2ec9e3430a4d0c8f05e89fabbc2659 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/package.json @@ -0,0 +1,13 @@ +{ + "name": "entry", + "version": "1.0.0", + "ohos": { + "org": "huawei", + "buildTool": "hvigor", + "directoryLevel": "module" + }, + "description": "example description", + "repository": {}, + "license": "ISC", + "dependencies": {} +} diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/entryability/EntryAbility.ts b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/entryability/EntryAbility.ts new file mode 100644 index 0000000000000000000000000000000000000000..a548a4a610b5dd2da5ff1fa5173e9d21ccb88d97 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/entryability/EntryAbility.ts @@ -0,0 +1,51 @@ +import hilog from '@ohos.hilog'; +import Ability from '@ohos.application.Ability' +import Window from '@ohos.window' + +export default class EntryAbility extends Ability { + onCreate(want, launchParam) { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? ''); + } + + onDestroy() { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: Window.WindowStage) { + // Main window is created, set main page for this ability + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.ERROR); + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground() { + // Ability has brought to foreground + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground() { + // Ability has back to background + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/model/DataMock.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/model/DataMock.ets new file mode 100644 index 0000000000000000000000000000000000000000..bdcbd23c32d2e1a4bff0543ec901be444d68a180 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/model/DataMock.ets @@ -0,0 +1,59 @@ +import {CourseInfo, + MAXCOUNT, + Subject, + LearnWeek,LearnDay +} from "./DataModels" + +let CURRENT_TERM = "2022秋季青少年培训" +export let getCourseMockData:Array = [ + { Id:1,Title:"少儿舞蹈",Teacher:"吴老师", + Place:"教师T2-306", + Week: LearnWeek.Saturday, Day: LearnDay.AM, + Time: "9:00-11:00", + Subject: Subject.WUDAO , Term: CURRENT_TERM, + Descript:"仅限1-2年级女生", AgeRange:"", MaxLimit: MAXCOUNT, Enrolled:21 + }, + { Id:2,Title:"少儿围棋初级",Teacher:"王老师", + Place:"教师T2-307", + Week: LearnWeek.Saturday, Day: LearnDay.AM, + Time: "9:00-11:00", + Subject: Subject.QILEI, Term:CURRENT_TERM, + Descript:"围棋大师带教", AgeRange:"", MaxLimit: MAXCOUNT,Enrolled:5 + }, + { Id:3,Title:"尤克里里",Teacher:"刘老师", + Place:"教师T2-204", + Week: LearnWeek.Saturday, Day: LearnDay.PM, + Time: "9:00-11:00", + Subject: Subject.YINYUE, Term:CURRENT_TERM, + Descript:"包含乐器成本", AgeRange:"", MaxLimit: MAXCOUNT,Enrolled:10 + }, + { Id:4,Title:"初级素描班",Teacher:"陈老师", + Place:"教师T2-301", + Week: LearnWeek.Saturday, Day: LearnDay.PM, + Time: "9:00-11:00", + Subject: Subject.HUIHUA, Term:CURRENT_TERM, + Descript:"无基础入门,自带画具", AgeRange:"", MaxLimit: MAXCOUNT,Enrolled:14 + }, + { Id:5,Title:"儿童绘画班",Teacher:"林老师", + Place:"教师T2-301", + Week: LearnWeek.Sunday, Day: LearnDay.AM, + Time: "9:00-11:00", + Subject: Subject.HUIHUA, Term:CURRENT_TERM, + Descript:"仅限大小班", + AgeRange:"", MaxLimit: MAXCOUNT,Enrolled:14 + }, + { Id:6,Title:"中级素描班",Teacher:"阙老师", + Place:"教师T2-301", + Week: LearnWeek.Sunday, Day: LearnDay.AM, + Time: "9:00-11:00", + Subject: Subject.HUIHUA, Term:CURRENT_TERM, + Descript:"", AgeRange:"", MaxLimit: MAXCOUNT,Enrolled:14 + }, + { Id:7,Title:"高级素描班",Teacher:"傅老师", + Place:"教师T2-301", + Week: LearnWeek.Sunday, Day: LearnDay.PM, + Time: "9:00-11:00", + Subject: Subject.HUIHUA, Term:CURRENT_TERM, + Descript:"仅限有素描基础入门,无中级资格勿报", AgeRange:"", MaxLimit: MAXCOUNT,Enrolled:14 + }, +] \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/model/DataModels.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/model/DataModels.ets new file mode 100644 index 0000000000000000000000000000000000000000..37b833ebd2860954f45388f42511e91ffab3c594 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/model/DataModels.ets @@ -0,0 +1,68 @@ +export enum LearnWeek { + Monday = 1, + Tuesday , + Wednesday, + Thursday, + Friday, + Saturday, + Sunday +} + +export const MAXCOUNT :number= 24 + +export enum LearnDay { + AM = 1, + PM +} + +export enum Subject { + WUDAO = 1, //舞蹈 + QILEI, //棋类 + HUIHUA , //绘画 + YINYUE, //音乐 + SPORT, //体育 + SHUFA , //书法 + SHOUGONG //手工 +} + + + + +export type Student = { + Id :number + Name: string + BirthDay: number + Mobile : string +} + +// 教师 +// 上课时间 +// 上课地点 +// 学科 +//学期 +//课程描述 +//学员年龄限制 +//学生数量 +//查看学员 +export type CourseInfo ={ + Id :number + Title :string + Teacher: string + Week: LearnWeek + Day: LearnDay + Time: string + Place : string + Subject : Subject + Term : string + Descript: string + AgeRange: string + MaxLimit : number + Enrolled : number +} + + + +export class CourseRecord { + Members : Array +} + diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/Index.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..21070679cb6c97c940a3ae3c05e0639b13da09c2 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,21 @@ +import router from "@ohos.router" + +@Entry +@Component +struct Index { + + build() { + Column() { + Button("baoming").onClick( () => { + router.push({ + url: "pages/enroll", + params: { + } + }) + } + ) + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/checkin.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/checkin.ets new file mode 100644 index 0000000000000000000000000000000000000000..625f354d92c1207ec1d6617cf2a5f00954e80cea --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/checkin.ets @@ -0,0 +1,233 @@ +/** + * 课程签到记录 + */ +import router from '@ohos.router'; +import {Profile} from './profile' +@Preview +@Component +@Entry +struct Checkin { + controller: TabsController = new TabsController() + build(){ + Column(){ + + //签到记录 +// Text("签到日志") +// CheckRecords() + //底部tab + Tabs( { barPosition: BarPosition.End + ,index : 0 + , controller: this.controller }){ + TabContent(){ + Column(){ + Image($r('app.media.checkin_top')) + .objectFit( ImageFit.Cover) + .height(200) + WeekCourses({ tasks: getTasks}) + .margin({ top:-20}) + } .width('100%') + .height('100%') + + + + }.tabBar("课程") + TabContent(){ + Profile() + }.tabBar("个人") + } + } + .width('100%') + .height('100%') + .linearGradient({ + direction: GradientDirection.Bottom, // 渐变方向 + repeating: false, // 渐变颜色是否重复 + colors: [[0xb1d4d6, 0.2],[0xb1d4d6, 0.2], [0xffffff, 0.9]] + }) + } +} +type Task = { + Id :number + Name: string + CourseId: number + DoneTime: string + IsDone: boolean + Time: string +} + +let getTasks:Array= [ + { Id:1, Name:"尤克里里", CourseId:1, DoneTime:"",IsDone:false, Time: "9:00"}, + { Id:2, Name:"素描", CourseId:2, DoneTime:"",IsDone:true , Time: "14:00"}, + { Id:3, Name:"低级素描", CourseId:3, DoneTime:"",IsDone:false , Time: "16:00"}, +] + +import {CheckinDialog, SuccessDialog} from './dialog' +/** + * 本周课程 + */ +//@Preview + +@Component +struct WeekCourses { + private tasks:Array + + build(){ + + Column({ space:10}){ + Text("本周课程") + .margin(20) + .width('100%') + .fontSize(20).textAlign( TextAlign.Start) + +// if( this.tasks.length == 0 ){ + Row(){ + Text("尚未报名").fontSize(16) + Text("点击进入").onClick(() =>{ + router.push({ + url:"pages/enroll" + }) + }).fontSize(16) + .fontColor(Color.Blue) + .margin({ left:20}) + .border({style:{ bottom: BorderStyle.Solid},width:{ bottom:2}}) + } +// }else{ + + ForEach( this.tasks, (row:Task,idx) => { + UserTask({ + task : row, + courseId : row.Id, + checked: row.IsDone}) + }) +// } + } + .width('90%') + .backgroundColor(0xffffff) + .padding(20) + .borderRadius({ topLeft:20,topRight:20}) + + + } +} +//@Preview +@Component +struct UserTask { + @State @Watch("resultChagned") result :boolean = false + @State checked : boolean = false + private courseId:number + task:Task + + dialogController: CustomDialogController = new CustomDialogController({ + builder: CheckinDialog({ + cancel: this.onCancel, + confirm: this.onAccept, +// courseId: $courseId, + result: $result + }), + cancel: this.onCancel, + autoCancel: true, + alignment: DialogAlignment.Default, + offset: { dx: 0, dy: -20 }, + gridCount: 8, + customStyle: false + }) + + successController: CustomDialogController = new CustomDialogController({ + builder: SuccessDialog({ + }), + alignment: DialogAlignment.Default, + gridCount:4, + customStyle: true + }) + + onCancel() { + console.log( "cancel") + } + //弄出一个东西能从小到大 按某特效 提示 + onAccept() { + //到时候又弹出成功弹窗 + console.log("accept") +// console.debug( this.result ? "t":"f") + } + + resultChagned() { + console.log( this.result+ "") +// console.log( "before"+this.checked+"") + if(this.result){ + this.checked = true + }else{ + this.checked = false + } + if(this.result){ + this.successController.open() + setTimeout(() => { + this.successController.close() + },2000) + } +// console.log( "after:" + this.checked+"") +// console.log( typeof this.successController ) + } + + aboutToAppear(){ +// console.log( typeof this.successController) + } + + build() { + Row(){ + Text( this.task.Name) + .width('70%') + if( this.checked ){ + //已签到 + Button( "已签到") + .backgroundColor(0xdddddd) + .width('30%') + }else{ + Button( "签到").onClick( () => { + //弹出一个对话框卡 +// this.checked = !this.checked + this.dialogController.open() +// this.successController.open() + }) + .width('30%') + } +// Text(this.checked+"") + + } +// this.successController; + } +} + + + +@Component +//@Preview +struct CheckRecords { + private records:Array = [ + "", + "", + "" + ]; + build(){ + Column(){ + List({ space:10}) { + ForEach(this.records , ( row) => { + ListItem(){ + Row(){ + //用画布绘画节点 +// Image() + Rect({width:20, height:50}).fill( Color.White) + + + Column(){ + Text("签到课程") + Text("签到时间") + }.width('80%') + .height(50) + + } + } + }) + + } + } + } +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/detail.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/detail.ets new file mode 100644 index 0000000000000000000000000000000000000000..71ab6ca6bf3fc1e0a843bdaab6621447b1e61f56 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/detail.ets @@ -0,0 +1,96 @@ +/** + * 课程详情页面 + */ +export class InfoCol { + Field:string + Value:string + Key : string +} + +type ColDefine = { + Text: string + Key: string +} +import { CourseInfo} from "../model/DataModels" +import router from '@ohos.router' +@Entry +@Preview +@Component +struct Detail { + @State courseinfo : CourseInfo = router.getParams()['course'] + private cols : Array = [ + { Text:"教师",Key:"Teacher"}, + { Text:"上课时间",Key:"Time"}, + { Text:"教室地点",Key:"Place"}, + { Text:"学科",Key:"Subject"}, + { Text:"报名学员",Key:"Teacher"}, + { Text:"报名限制",Key:"AgeRange"}, + ] + build(){ + Column(){ + Image($r('app.media.Course')) + .height(200) + .width('100%') + .objectFit( ImageFit.Contain ) + Text( this.courseinfo.Title ) + .fontSize(30) + Text( this.courseinfo.Descript) + .fontSize(20) + .fontColor(0xcccccc) + .margin({top:20}) + + ForEach(this.cols,(row:ColDefine,idx) => { +// Text( idx % 2 + "1") + DetailItem({ + isodd: idx % 2 === 0 ? true : false, + field: row.Text, + value: this.courseinfo[row.Key] + }) + }) + } +// .border({bottom:1}) + + .height('100%') + .width('100%') + + } +} +@Styles +function borderBottomGrey() { + .border({ style:{ + bottom: BorderStyle.Solid}, + width:{ bottom:1}, + color:{ bottom:0xdddddd} + }) +} + + +@Preview +@Component +struct DetailItem { + @State isodd:boolean = false + private field: string = "" + private value : string = "" + build(){ + Column(){ + Row(){ +// Text( this.isodd ? "true": "false") + Text( this.field).width('50%').height(50) + .textAlign( TextAlign.End) + .fontSize(18) + .fontColor(0x888888) + .backgroundColor( this.isodd ? 0xeeeeee : 0xfefefe) + .padding({right:20}) + Text(this.value) + .width('50%').height(50) + .textAlign( TextAlign.Start) + .padding({left: 20}) + .fontSize(18) + .borderBottomGrey() + } + + } + .width('100%') + .height(50) + } +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/dialog.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/dialog.ets new file mode 100644 index 0000000000000000000000000000000000000000..55517d53ba969ab33bf210d663aaf688f4f7899b --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/dialog.ets @@ -0,0 +1,104 @@ +/** + * 自定义签到弹窗 + */ +//@Preview +@CustomDialog +export struct CheckinDialog { + controller: CustomDialogController + cancel: () => void + confirm: () => void + @Link result : boolean + + + build(){ + Column(){ + Text("课程标题") + .width('100%') + .fontSize(20) + .fontWeight(700) + .padding({left:20}) + .margin({ top: 150}) + Button("check").onClick( () => { + this.controller.close() + this.result = true + this.confirm() + }) + } + .width('80%') + .height(300) + .backgroundImage($r('app.media.Course')) + .opacity(0.7) + .backgroundImageSize( ImageSize.Cover) + } +} + +const CHECK_OK = "签到成功" +@CustomDialog +export struct SuccessDialog { + controller: CustomDialogController; +// @Link result: boolean + @State angle : number = 0 + @State opacityval: number = 0 + @State scalaval: number = 0 + build(){ + Column(){ + Image($r('app.media.gift1')) +// .objectFit(ImageFit.Contain) + Text( CHECK_OK ) + } + .backgroundColor( Color.Transparent) + .width(200) + .height(60) + .gesture( TapGesture().onAction( () => { + this.controller.close() + })) + .justifyContent( FlexAlign.Center) + .scale({x: this.scalaval,y: this.scalaval}) + .rotate({x:0,y:1,z:0, angle: this.angle}) + .opacity( this.opacityval) + .onAppear(() =>{ + animateTo({ + duration:1000, + curve: Curve.EaseOut, iterations:1, delay:100 + }, () => { + this.scalaval = 1 + this.opacityval = 1 + this.angle = 360 +// this.result = true + }) + }) + } +} + +/** + * 出生年月选择 + */ +@CustomDialog +export struct CalenderDialog { + controller: CustomDialogController; + @Link selectedDate: Array + build(){ + Column(){ + DatePicker({ + start: new Date('2000-1-1'), + end: new Date('2020-1-1'), + selected: new Date(this.selectedDate.join('-')), + }) + .width(200) + .lunar(false) + .onChange((value: DatePickerResult) => { +// console.log( value+""); + this.selectedDate = [value.year+"", value.month + 1+"", value.day+""] +// console.info('select current date is: ' + JSON.stringify(value)) + }).height(400) + Flex({ justifyContent: FlexAlign.Center}){ + Button("确定").onClick(() => { + this.controller.close() + }) + }.margin({bottom:50}) + } + .backgroundColor(Color.White) + .borderRadius(20) + .margin(50) + } +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/enroll.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/enroll.ets new file mode 100644 index 0000000000000000000000000000000000000000..db1c92a16d2dafa652dc6ca79300a840b9b258d1 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/enroll.ets @@ -0,0 +1,353 @@ +import { getCourseMockData} from '../model/DataMock' +import { CourseInfo, LearnWeek, LearnDay} from "../model/DataModels" +import router from "@ohos.router" + +@Preview +@Entry +@Component +struct EnrollPage { + @State showId : number = 0 + @State show: boolean = false + @Provide("selectnum") @Watch('onListenCount') selectCount :number = 0 + @Provide("selectcourse") @Watch('onListenCourse') selectCourse:Array = [] + + onListenCount() { + if(this.selectCount > 0){ + this.show = true + }else{ + this.show = false + } + } + + onListenCourse(){ + console.log( this.selectCourse.length + "") + //处理移除的课程状态取消 + + } + + @State selectedCourse: Array = []; + private controller: TabsController = new TabsController() + @State currentIndex:number = 0 + + tabs : Array = [ + "周六上午", + "周六下午", + "周日上午", + "周日下午" + ] + + @Builder TabBuilder(index: number,name:string) { + Column() { + Text(`${name}`) + .fontColor(this.currentIndex === index ? 0xffffff : 0x333333) + .fontSize(12) + } + .height(50) + .backgroundColor(this.currentIndex === index ? Color.Blue : 0xeeeeee) + .width('100%') + .justifyContent( FlexAlign.Center) + } + build(){ + + Stack({alignContent: Alignment.Bottom }){ +// Button("switch").onClick( () => { +// this.showId = (this.showId == 0 ? 1 : 0) +// }) + Tabs({ barPosition: BarPosition.Start, + controller: this.controller }) { + + ForEach(this.tabs, (tab ,idx) => { + TabContent() { + CourseList( {weekgroup:idx}) + }.tabBar( this.TabBuilder(idx,tab)) + + }) + } +// .vertical(true) + .scrollable(false) + .barMode(BarMode.Fixed) + .barWidth('100%') + .barHeight(50) + .animationDuration(100) + .onChange((index: number) => { + this.currentIndex = index +// console.info(index.toString()) + }) + .width('100%') + .backgroundColor(0xF5F5F5) + .height('100%') + + SelectedCourse({show:$show}) +// .zIndex( this.show ? 3: -1) +// .visibility(this.show ? Visibility.Visible: Visibility.Hidden) + EnrollBar() + } + } +} + +//@Preview +@Component +struct CourseList { + weekgroup : number + @Consume("selectnum") selectNums : number + @Consume("selectcourse") selected: Array + private arr :Array = getCourseMockData + + processSelected = ( state, course:CourseInfo) => { + if(state){ +// console.log("selected") + this.selectNums += 1 +// console.log(course.Title) + //先判断是否存在相同的 + if(!this.selected.includes(course)){ + this.selected.push( course) + } + }else{ +// console.log( "no selected") + this.selectNums -= 1 + this.selected.splice(this.selected.indexOf( course),1) + } + } + + filterDate( w :number,d:number){ +// console.log( this.weekgroup+"") + if( this.weekgroup == 0){ + return w == LearnWeek.Saturday && d == LearnDay.AM + }else if( this.weekgroup == 1){ + return w == LearnWeek.Saturday && d == LearnDay.PM + }else if( this.weekgroup == 2){ + return w == LearnWeek.Sunday && d == LearnDay.AM + }else { + return w == LearnWeek.Sunday && d == LearnDay.PM + } + } + + + build(){ + Scroll(){ + List({ space:2}){ + ForEach( this.arr.filter( row => this.filterDate( row.Week ,row.Day ), this), + (item,idx ) => { + ListItem(){ + CourseItem( { + courseinfo: item + ,selected: this.selected.indexOf(item) > 0 ? true: false + ,onSelected: this.processSelected + }) + } + }) + } + } + .width('100%') + .backgroundColor("#efefef") + } +} +@Component +//@Preview +struct CourseItem { + private courseinfo: CourseInfo = null + onSelected : ( boolean, CourseInfo) => void + @State selected : boolean = false + + build(){ + Row({space:6}){ + Column(){ + Row(){ + Text(`#${this.courseinfo.Id} ${this.courseinfo.Title}`) + .fontSize( 18) + .textAlign(TextAlign.Start) + .width( 150) + Text( this.courseinfo.Time) + .fontSize(16) + } + + Text(this.courseinfo.Descript) + .fontSize(14) + .textAlign( TextAlign.Start) + .width('100%') + .fontColor( Color.Gray) + } + .width('70%') + .gesture( + LongPressGesture() + .onAction(() => { +// console.log(this.courseinfo.Id + "long press") +// this. += '\nText'; + router.push({ + url:"pages/detail", + params: { course: this.courseinfo } + }) + })) + //long press to go detail + Row(){ + Text(`还剩${this.courseinfo.MaxLimit - this.courseinfo.Enrolled}人`) + .fontColor( Color.Gray) + } + .justifyContent( FlexAlign.End) + .width('30%') + } + .height(90) + .width('100%') + .padding(20) + .onClick(() => { + //选中背景色 + console.log( this.selected+"") + this.selected = !this.selected; + this.onSelected(this.selected, this.courseinfo) + + + }) + .backgroundColor( this.selected ? 0xc7ebc7: Color.White) + } +} +/** + * 已选择的课程的区域 + * 自行模拟 + */ +//@Preview +@Component +struct SelectedCourse { + @Link show :boolean + @Consume("selectnum") count: number + @Consume("selectcourse") course : Array + + //响应课程取消回调 + removeCourse = (c:CourseInfo) => { +// console.log( ""+this.count) + this.course.splice( this.course.indexOf(c),1) + this.count -= 1 +// console.log("callback remove") + } + + build() { + Column() { + + Row() { + Button("清空").onClick(() => { + this.course = [] + this.count = 0 + }) + }.margin({ top:30,bottom:5}) + .width('100%') + Text("提示:每人最多选两科课程").width('100%') + .fontColor(0x888888) + .fontSize(11) + .padding(10) + Divider().color(0xcccccc) + List({space:10}){ + ForEach(this.course, (c) => { + ListItem(){ + SelectedCourseItem({ + course: c, + onDelete: this.removeCourse + }) + } + }) + } + + } + .translate( this.show ? { x:0,y:0}:{x:0,y:'100%'}) + .animation({ duration:2500}) + .backgroundColor(0xefefef) + .width('100%') + .height('100%') + .position({x:0, y:'50%'}) + .borderRadius({ topLeft: 30, topRight: 30 }) + .margin({ bottom: 50 }) + } +} +//@Preview +@Component +struct SelectedCourseItem { + onDelete:(CourseInfo) => void + course:CourseInfo + build(){ + Row({space:10}){ + Text(this.course.Title) + .width('80%') + .textAlign(TextAlign.Start) + .fontSize(20) + .padding({left:10}) + + Row(){ + Button("-").backgroundColor(0xdddddd).fontWeight(700) + .onClick(() => { + this.onDelete(this.course) + }) + } + } + .width('100%') + .height(60) + .backgroundColor(0xffffff) + } +} + +/** + * 报名的课程 工具条 + */ +@Component +struct EnrollBar { + @Consume('selectnum') @Watch("onListenCount") count: number + @State show: boolean = false + onListenCount(p:string){ + console.log(p) + if(this.count > 0){ + this.show = true + }else{ + this.show = false + } + } + @State showpop :boolean = false + build(){ + Column(){ + + Row(){ + Row(){ + + Text(`已选${this.count}门`) + .margin({ left:20}) + .fontSize(14) + .onClick( () => { + this.show = !this.show + }) + }.width('50%') + Row(){ + Button("报名",{ type: ButtonType.Normal}) + .backgroundColor(0x777777) + .margin( {right:20, top:20}) + .onClick(() =>{ + this.showpop = true + }) + .bindPopup(this.showpop, { + message: '确认报名以上课程?', + placementOnTop: true, + primaryButton: { + value: '确认', + action: () => { + this.showpop = !this.showpop +// console.info('confirm Button click') + + } + } + }) + } + .justifyContent( FlexAlign.End) + .width('50%') + } + .justifyContent(FlexAlign.Center) + .alignItems(VerticalAlign.Center) + .align( Alignment.Center) + + + } + .backgroundColor(0xdddddd) + .position({ x:0,y:'90%'}) + .width('100%') + .height('100%') + + } +} + + + + diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/logo.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/logo.ets new file mode 100644 index 0000000000000000000000000000000000000000..772c1a457222494448a4c378671ef68237ddf9f7 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/logo.ets @@ -0,0 +1,82 @@ +import router from '@ohos.router'; +import curves from '@ohos.curves'; + +@Extend(Text) function tongyiStyle(){ + .fontSize(30) + .fontWeight(700) +} + +@Entry +@Preview +@Component +struct Logo { + message: string = "好好学习" + message2 :string = "天天向上" + + aboutToAppear(){ +// setTimeout(() => { +// router.push({ +// url: "/pages/checkin.ets", +// params: { +// } +// }) +// },2000) + } + @State scaleValue:number= 0 + @State opacityValue :number= 0 + + @Styles donghua(){ + .scale({ x: this.scaleValue, y: this.scaleValue }) + .opacity(this.opacityValue) + .onAppear(() => { + animateTo({ + duration: 1000, + curve: curves.cubicBezier(0.4, 0, 1, 1), + delay: 100, + onFinish: () => {} + }, () => { + this.opacityValue = 1 + this.scaleValue = 1 + }) + }) + } + @Styles donghuaWithRedirect(){ + .scale({ x: this.scaleValue, y: this.scaleValue }) + .opacity(this.opacityValue) + .onAppear(() => { + animateTo({ + duration: 1000, + curve: curves.cubicBezier(0.4, 0, 1, 1), + delay: 2000, + onFinish: () => { + setTimeout(() => { + router.replace({ url: 'pages/checkin' }) + }, 1000) + } + }, () => { + this.opacityValue = 1 + this.scaleValue = 1 + }) + }) + } + + + + build() { + Column() { + Flex({ + direction: FlexDirection.Column, + justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}) { + Image($r('app.media.sunshine')).height(150).width(150).donghua() + Text(this.message).tongyiStyle() + .margin({ bottom: 30 }).donghua() + Text(this.message2).tongyiStyle() + .donghuaWithRedirect() + } + .height('100%') + .align(Alignment.Center) + .width('100%') + }.height('100%') + .linearGradient({ angle: 180, colors: [['#BDE895', 0.1], ['#95DE7F', 0.6], ['#7AB967', 1]] }) + } +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/profile.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/profile.ets new file mode 100644 index 0000000000000000000000000000000000000000..a102e4eeee8b74f10490aa477e0d633c0c8644e5 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/ets/pages/profile.ets @@ -0,0 +1,152 @@ +/** + * 个人信息等级 + */ +@Preview +@Component +export struct Profile { + + + build(){ + Column(){ + Flex({ justifyContent: FlexAlign.Center}){ + Image($r('app.media.touxiang')) + .height(100) + .width(100) + .borderRadius(100) + .backgroundColor(0xfffffff) + .margin({top:20,bottom:20}) + } + .height(150) + .width('100%') + .backgroundColor(0xdddddd) + + //下面是信息登记 + Form() + + }.width('100%') + .height('100%') + } +} + +@Styles function formFieldStyle(){ + .width(80) + .padding({ left:20}) +} + +@Extend(Text) function setFieldFont(){ + .fontSize(18) + .fontColor(0x777777) + .fontWeight(FontWeight.Normal) +} + +const GENDER_MALE= "男" +const GENDER_FEMALE= "女" +import { CalenderDialog} from './dialog' + +@Component +struct Form { + + + @State gender :string = GENDER_MALE + @State selectedDate: Array = ['2000','01','01'] + + dateController: CustomDialogController = new CustomDialogController({ + builder: CalenderDialog({ + selectedDate: $selectedDate + }), + alignment: DialogAlignment.Default, + gridCount:4, + customStyle: true + }) + + build(){ + Column(){ + Row() { + Text('姓名').formFieldStyle().setFieldFont() + TextInput({ placeholder: '输入姓名'}) + .layoutWeight(1) + .type(InputType.Normal) + .placeholderColor(Color.Gray) + .fontSize(19) + .maxLength(20) + .margin({ left: 10 }) + .onChange((value: string) => { + // this.foodItem.age = value + }) + }.margin({ top: 20}) + Row() { + Text('身份证').formFieldStyle().setFieldFont() + TextInput({ placeholder: '输入身份证号码'}) + .layoutWeight(1) + .type(InputType.Normal) + .placeholderColor(Color.Gray) + .fontSize(19) + .maxLength(20) + .margin({ left: 10 }) + .onChange((value: string) => { + // this.foodItem.age = value + }) + }.margin({top:20}) + Row() { + Text("性别").formFieldStyle().setFieldFont() + Row() { + Toggle({ type: ToggleType.Switch, isOn: true }) + .selectedColor(0x39a2db) + .switchPointColor(0xe5ffffff) + .onChange((isOn: boolean) => { +// console.log(isOn+"") + if (isOn) { + this.gender = GENDER_MALE + } else { + this.gender = GENDER_FEMALE + } + // console.info('Component status:' + isOn) + }) +// } + Text(this.gender).setFieldFont() + }.width(280) + }.margin({ top: 20 }) + +// 出生年月 + Row(){ + Text("出生年月").formFieldStyle().setFieldFont() + Flex({ justifyContent:FlexAlign.Center, alignItems: ItemAlign.Center}){ + Text(`${this.selectedDate[0]}年`).flexGrow(1).fontSize(18) + Text(`${this.selectedDate[1]}月`).flexGrow(1).fontSize(18) + Text(`${this.selectedDate[2]}日`).flexGrow(1).fontSize(18) + + }.onClick( ()=> { + this.dateController.open() + }) + .height(50).width(280) + }.margin({ top: 20 }) +// 家长联系方式 + Row() { + Text("联系方式").formFieldStyle().setFieldFont() + Row() { + TextInput({ placeholder: '输入家长手机号码'}) + .layoutWeight(1) + .type(InputType.Normal) + .placeholderColor(Color.Gray) + .fontSize(19) + .maxLength(20) + .margin({ left: 10 }) + .onChange((value: string) => { + // this.foodItem.age = value + }) + }.width(280) + }.margin({ top: 20 }) + Flex({ justifyContent: FlexAlign.Center}){ + Button("提交",{ type: ButtonType.Capsule}) + .width(100) + }.width('100%').margin({top:100}) + + + + } + } +} + + + + diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/module.json5 b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..0e288c05b41ef026b9f802f6c848bd5301ebc785 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/module.json5 @@ -0,0 +1,37 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntrance": "./ets/entryability/EntryAbility.ts", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "visible": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/element/color.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/element/string.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/Course.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/Course.png new file mode 100644 index 0000000000000000000000000000000000000000..8051e19a6e0c7976ee7f6b7aca60b6d19385f0d8 Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/Course.png differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/checkin_top.jpg b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/checkin_top.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3d4809e24293a49e4d5b18426623d7ad87b0d453 Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/checkin_top.jpg differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/gift1.gif b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/gift1.gif new file mode 100644 index 0000000000000000000000000000000000000000..c8446c445b6d1a56fa9576af991ca7f634cc526d Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/gift1.gif differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/icon.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/icon.png differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/sunshine.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/sunshine.png new file mode 100644 index 0000000000000000000000000000000000000000..89cfac2fbd58cf7d8e15cb071b5c64cca9db2edb Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/sunshine.png differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/touxiang.jpg b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/touxiang.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4fdca6ca1edcb566f1aa0b4f9b516e3293e186d1 Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/media/touxiang.jpg differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/profile/main_pages.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..0bfb5f34f748a7dec6416a9d6eb26db848d6470b --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,8 @@ +{ + "src": [ + "pages/logo", + "pages/detail", + "pages/enroll", + "pages/checkin" + ] +} diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/en_US/element/string.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/zh_CN/element/string.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/test/Ability.test.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..460fe8c8c124c821c5451615acc8949f619dbc3f --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,36 @@ +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/test/List.test.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..d766fe249dfc3ada636f27e64d9b64451ce32c93 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/testability/TestAbility.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..84765c417cbff3b90c08d4c9accb2ea581ba2df1 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,57 @@ +import hilog from '@ohos.hilog'; +import Ability from '@ohos.application.Ability' +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' +import { Hypium } from '@ohos/hypium' +import testsuite from '../test/List.test' +import Window from '@ohos.window' + +export default class TestAbility extends Ability { + onCreate(want, launchParam) { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: Window.WindowStage) { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.ERROR); + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/testability/pages/Index.ets b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..954dfe0e29874c9ef11a5ace1673f79e27999864 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,35 @@ +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..94579b9c1535bc11ee56ee53b48fc90a9977e33a --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,71 @@ +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner' +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +function translateParamsToString(parameters) { + const keySet = new Set([ + '-s class', '-s notClass', '-s suite', '-s it', + '-s level', '-s testType', '-s size', '-s timeout', + '-s dryRun' + ]) + let targetParams = ''; + for (const key in parameters) { + if (keySet.has(key)) { + targetParams = `${targetParams} ${key} ${parameters[key]}` + } + } + return targetParams.trim() +} + +async function onAbilityCreateCallback() { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + cmd += ' '+translateParamsToString(abilityDelegatorArguments.parameters) + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/module.json5 b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..476d15376f43323426498a79fb3d58a658a27a56 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/module.json5 @@ -0,0 +1,37 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntrance": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "visible": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/element/color.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/element/string.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/media/icon.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/profile/test_pages.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/hvigorfile.ts b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..6478186902c0c1ad7c966a929c7d6b7d8ae7a9f3 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/check_dialog.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/check_dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..1648838e9f95f7a4e3cf3f5ea0ede660aa3b8be6 Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/check_dialog.png differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/checkin.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/checkin.png new file mode 100644 index 0000000000000000000000000000000000000000..2281f0c5b05ab4c0e77ff75a079f0c9a79cc2294 Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/checkin.png differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/detail.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/detail.png new file mode 100644 index 0000000000000000000000000000000000000000..b038ff96b00276762334c19a3a1b69feff8277e3 Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/detail.png differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/enroll.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/enroll.png new file mode 100644 index 0000000000000000000000000000000000000000..983fe4cc544d7e51a0f02cf00c1a7ab6efbdfb56 Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/enroll.png differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/page_datepick.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/page_datepick.png new file mode 100644 index 0000000000000000000000000000000000000000..21a9f1ae6471f88894f91fcc7e823f71b10fd060 Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/page_datepick.png differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/page_logo.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/page_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c174e0a148de12854279bbc4f74044dd0947e300 Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/page_logo.png differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/page_profile.png b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/page_profile.png new file mode 100644 index 0000000000000000000000000000000000000000..2823e17689b63e12011a82005e4a715def67df61 Binary files /dev/null and b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/page_profile.png differ diff --git "a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/\346\223\215\344\275\234\346\274\224\347\244\272.gif" "b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/\346\223\215\344\275\234\346\274\224\347\244\272.gif" new file mode 100644 index 0000000000000000000000000000000000000000..6d744140d510ea7bfbeaace8c3df5db520c3acfa Binary files /dev/null and "b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/images/\346\223\215\344\275\234\346\274\224\347\244\272.gif" differ diff --git a/2022_ArkUI_Bootcamp/chenwenli89+sng_app/package.json b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/package.json new file mode 100644 index 0000000000000000000000000000000000000000..51342c0b9cb651443a7352e2e9944885eeaf23b2 --- /dev/null +++ b/2022_ArkUI_Bootcamp/chenwenli89+sng_app/package.json @@ -0,0 +1,17 @@ +{ + "name": "sngapp", + "version": "1.0.0", + "ohos": { + "org": "huawei", + "buildTool": "hvigor", + "directoryLevel": "project" + }, + "description": "example description", + "repository": {}, + "license": "ISC", + "dependencies": { + "@ohos/hypium": "1.0.3", + "@ohos/hvigor": "1.3.1", + "@ohos/hvigor-ohos-plugin": "1.3.1" + } +}