页面效果
代码结构
代码
data
BannerData.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
[ { "id": 0, "imageSrc": "app.media.banner_pic0", "url": "https://developer.huawei.com/consumer/cn/training/course/video/C101718352529709527" }, { "id": 1, "imageSrc": "app.media.banner_pic1", "url": "https://developer.huawei.com/consumer/cn/" }, { "id": 2, "imageSrc": "app.media.banner_pic2", "url": "https://developer.huawei.com/consumer/cn/deveco-studio/" }, { "id": 3, "imageSrc": "app.media.banner_pic3", "url": "https://developer.huawei.com/consumer/cn/arkts/" }, { "id": 4, "imageSrc": "app.media.banner_pic4", "url": "https://developer.huawei.com/consumer/cn/arkui/" }, { "id": 5, "imageSrc": "app.media.banner_pic5", "url": "https://developer.huawei.com/consumer/cn/sdk" } ] |
EnablementData.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
[ { "id": 1, "imageSrc": "app.media.enablement_pic1", "title": "HarmonyOS第一课", "brief": "基于真实的开发场景,提供向导式学习,多维度融合课程等内容,给开发者提供全新的学习体验。", "webUrl": "https://developer.huawei.com/consumer/cn/doc/harmonyos-video-courses/video-tutorials-0000001443535745" }, { "id": 2, "imageSrc": "app.media.enablement_pic2", "title": "开发指南", "brief": "提供系统能力概述、快速入门,用于指导开发者进行场景化的开发。指南涉及到的知识点包括必要的背景知识、符合开发者实际开发场景的操作任务流(开发流程、开发步骤、调测验证)以及常见问题等。", "webUrl": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/application-dev-guide-0000001630265101" }, { "id": 3, "imageSrc": "app.media.enablement_pic3", "title": "最佳实践", "brief": "针对新发布特性及热点特性提供详细的技术解析和开发最佳实践。", "webUrl": "https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/topic-architecture-0000001678045510" }, { "id": 4, "imageSrc": "app.media.enablement_pic4", "title": "Codelabs", "brief": "以教学为目的的代码样例及详细的开发指导,帮助开发者一步步地完成指定场景的应用开发并掌握相关知识。Codelabs将最新的鸿蒙生态应用开发技术与典型场景结合,让开发者快速地掌握开发高质量应用的方法。同时支持互动式操作,通过文字、代码和效果联动为开发者带来更佳的学习体验。", "webUrl": "https://developer.huawei.com/consumer/cn/doc/harmonyos-codelabs/codelabs-0000001443855957" }, { "id": 5, "imageSrc": "app.media.enablement_pic5", "title": "Sample", "brief": "面向不同类型的开发者提供的鸿蒙生态应用开发优秀实践,每个Sample Code都是一个可运行的工程,为开发者提供实例化的代码参考。", "webUrl": "https://developer.huawei.com/consumer/cn/doc/harmonyos-samples/samples-0000001162414961" }, { "id": 6, "imageSrc": "app.media.enablement_pic6", "title": "API参考", "brief": "面向开发者提供鸿蒙系统开放接口的全集,供开发者了解具体接口使用方法。API参考详细地描述了每个接口的功能、使用限制、参数名、参数类型、参数含义、取值范围、权限、注意事项、错误码及返回值等。", "webUrl": "https://developer.huawei.com/consumer/cn/doc/harmonyos-references/development-intro-0000001580026066" }, { "id": 7, "imageSrc": "app.media.enablement_pic7", "title": "FAQ", "brief": "开发者常见问题的总结,开发者可以通过FAQ更高效地解决常见问题。FAQ会持续刷新,及时呈现最新的常见问题。", "webUrl": "https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs/faqs-development-0000001753952202" }, { "id": 8, "imageSrc": "app.media.enablement_pic8", "title": "开发者论坛", "brief": "和其他应用开发者交流技术、共同进步。", "webUrl": "https://developer.huawei.com/consumer/cn/forum/home?all=1" } ]s |
TutorialData.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
[ { "id": 1, "imageSrc": "app.media.tutorial_pic1", "title": "Step1 开发入门:Hello World", "brief": "本篇教程实现了快速入门——一个用于了解和学习HarmonyOS的应用程序 。", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-HelloWorld" }, { "id": 2, "imageSrc": "app.media.tutorial_pic2", "title": "Step2 使用Swiper构建运营位", "brief": "Swiper组件提供滑动轮播显示的能力。Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-SwiperBanner" }, { "id": 3, "imageSrc": "app.media.tutorial_pic3", "title": "Step3 创建Item视图", "brief": "Item定义子组件相关特征。相关组件支持使用条件渲染、循环渲染、懒加载等方式生成子组件。", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-BuildItem" }, { "id": 4, "imageSrc": "app.media.tutorial_pic4", "title": "Step4 网格和列表组件的使用", "brief": "网格和列表组件中,当Item达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能,适合用于呈现同类数据类型或数据类型集", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-GridAndList" }, { "id": 5, "imageSrc": "app.media.tutorial_pic5", "title": "Step5 应用架构设计基础——MVVM框架", "brief": "ArkUI采取MVVM = Model + View + ViewModel模式,将数据与视图绑定在一起,数据更新时候会直接更新视图。", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-BasicArchitectureDesignPart1" }, { "id": 6, "imageSrc": "app.media.tutorial_pic6", "title": "Step6 应用架构设计基础——三层架构", "brief": "ArkWeb(方舟Web)提供了Web组件,用于在应用程序中显示Web页面内容,为开发者提供页面加载、页面交互、页面调试等能力。", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-BasicArchitectureDesignPart2" }, { "id": 7, "imageSrc": "app.media.tutorial_pic7", "title": "Step7 ArkWeb页面适配", "brief": "基于Web组件实现了快速入门案例中的课程学习界面,帮助开发者了解如何加载网络界面、本地界面以及如何进行网络权限的配置。", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-ArkwebPageAdaptation" }, { "id": 8, "imageSrc": "app.media.tutorial_pic8", "title": "Step8 通过结构数据构建页面", "brief": "在该教程中会根据对知识地图界面进行界面实现的分析以及相应的数据结构的设计,然后逐步实现知识地图中的两个界面。通过该章节,开发者可以了解到数据如何驱动UI更新。", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-DataDrivenUIUpdates" }, { "id": 9, "imageSrc": "app.media.tutorial_pic9", "title": "Step9 设置组件导航", "brief": "该教程会在“数据驱动UI更新”教程完成了知识地图相关界面开发的基础上,对代码进行修改,实现从知识地图页到知识地图详情页的组件路由导航,同时该教程中会讲解到Tabs的开发。", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-SettingUpComponentNavigation" }, { "id": 10, "imageSrc": "app.media.tutorial_pic10", "title": "Step10 原生智能:AI语音朗读", "brief": "为您的文章详情页添加文本转语音服务,朗读文章简介,手机在无网状态下系统应用无障碍(屏幕朗读)接入文本转语音能力,提供语音播报。", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-TTS" }, { "id": 11, "imageSrc": "app.media.tutorial_pic11", "title": "Step11 一次开发,多端部署", "brief": "通过对快速入门整体页面的分析,得出关键的界面适配点以及需要适配的关键组件,然后通过对关键适配点的逐步适配,完成整个应用的一多开发。", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-DevelopOnceDeployAnywhere" }, { "id": 12, "imageSrc": "app.media.tutorial_pic12", "title": "Step12 原生互联:分布式流转", "brief": "基于分布式流转相关能力,使得整个应用可以在不同设备间进行无缝的流转。该章节内容会涉及到流转的相关前提,如何进行流转的权限配置以及实现应用可流转。", "webUrl": "https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-DistributedFlow" } ] |
util
BufferUtil.ets
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import { util } from '@kit.ArkTS' export function bufferToString(buffer: ArrayBufferLike): string { let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM: true }) let resultPut = textDecoder.decodeWithStream(new Uint8Array(buffer), { stream: true }) return resultPut } |
model
ArticleClass.ets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
export class ArticleClass { id: string = '' imageSrc: string = '' title: string = '' brief: string = '' webUrl: string = '' constructor(id: string, imageSrc: string, title: string, brief: string, webUrl: string) { this.id = id this.imageSrc = imageSrc this.title = title this.brief = brief this.webUrl = webUrl } } |
BannerClass.ets
1 2 3 4 5 6 7 8 9 10 11 |
export class BannerClass { id: string = '' imageSrc: string = '' url: string = '' constructor(id: string, imageSrc: string, url: string) { this.id = id this.imageSrc = imageSrc this.url = url } } |
view
Banner.ets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
import { BannerClass } from '../model/BannerClass' import { bufferToString } from '../util/BufferUtil' @Preview @Component export struct Banner { @State bannerList: BannerClass[] = [] getBannerDataFromJSON() { getContext(this).resourceManager.getRawFileContent('BannerData.json').then(value => { // 获取buffer内容 // let buffer: ArrayBufferLike = value.buffer // 转换为字符串 // let res: string = bufferToString(buffer) // 解析为数据结构 // this.bannerList = JSON.parse(res) as BannerClass[] // 简写 this.bannerList = JSON.parse(bufferToString(value.buffer)) as BannerClass[] }) } aboutToAppear(): void { this.getBannerDataFromJSON() } build() { Swiper() { ForEach(this.bannerList, (item: BannerClass, index: number) => { Image($r(item.imageSrc)) .objectFit(ImageFit.Contain) .width('100%') .padding({ top: 11, left: 16, right: 16 }) .borderRadius(16) }, (item: BannerClass, index: number) => item.id) } .autoPlay(true) .loop(true) .indicator( new DotIndicator() .color('#1a000000') .selectedColor('#0A59F7') ) } } |
EnablementView.ets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
import { ArticleClass } from '../model/ArticleClass' import { bufferToString } from '../util/BufferUtil' @Component struct EnablementItem { @Prop enablementItem: ArticleClass build() { Column() { Image($r(this.enablementItem.imageSrc)) .width('100%') .objectFit(ImageFit.Cover) .height(96) .borderRadius({ topLeft: 16, topRight: 16 }) Text(this.enablementItem.title) .height(19) .width('100%') .fontSize(14) .textAlign(TextAlign.Start) .textOverflow({ overflow: TextOverflow.Ellipsis }) .maxLines(1) .fontWeight(400) .padding({ left: 12, right: 12 }) .margin({ top: 8 }) Text(this.enablementItem.brief) .height(32) .width('100%') .fontSize(12) .textAlign(TextAlign.Start) .textOverflow({ overflow: TextOverflow.Ellipsis }) .maxLines(2) .fontWeight(400) .fontColor('rgba(0, 0, 0, 0.6)') .padding({ left: 12, right: 12 }) .margin({ top: 2 }) } .width(160) .height(169) .borderRadius(16) .backgroundColor(Color.White) } } @Preview @Component export struct EnablementView { @State enablementList: Array<ArticleClass> = [] aboutToAppear(): void { this.getEnablementDataFromJSON() } getEnablementDataFromJSON() { getContext(this).resourceManager.getRawFileContent('EnablementData.json').then(value => { this.enablementList = JSON.parse(bufferToString(value.buffer)) as ArticleClass[] }) } build() { Column() { Text('赋能套件') .width('100%') .fontColor('#182431') .fontSize(16) .fontWeight(500) .fontFamily('HarmonyHeiTi-medium') .textAlign(TextAlign.Start) .padding({ left: 16 }) .margin({ bottom: 8.5 }) Grid() { ForEach(this.enablementList, (item: ArticleClass) => { GridItem() { EnablementItem({ enablementItem: item }) } }, (item: ArticleClass) => item.id) } .rowsTemplate('1fr') .columnsGap(8) .scrollBar(BarState.Off) .height(169) .padding({ top: 2, left: 16, right: 16 }) } .width('100%') .margin({ top: 18 }) } } |
TutorialView.ets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
import { ArticleClass } from '../model/ArticleClass' import { bufferToString } from '../util/BufferUtil' @Component struct TutorialItem { @Prop tutorialItem: ArticleClass build() { Row() { Column() { Text(this.tutorialItem.title) .height(19) .width('100%') .fontSize(14) .textAlign(TextAlign.Start) .textOverflow({ overflow: TextOverflow.Ellipsis }) .maxLines(1) .fontWeight(400) .margin({ top: 4 }) Text(this.tutorialItem.brief) .height(32) .width('100%') .fontSize(12) .textAlign(TextAlign.Start) .textOverflow({ overflow: TextOverflow.Ellipsis }) .maxLines(2) .fontWeight(400) .fontColor('rgba(0, 0, 0, 0.6)') .margin({ top: 5 }) } .height('100%') .layoutWeight(1) .alignItems(HorizontalAlign.Start) .margin({ right: 12 }) Image($r(this.tutorialItem.imageSrc)) .height(64) .width(108) .objectFit(ImageFit.Cover) .borderRadius(16) } .width('100%') .height(88) .borderRadius(16) .backgroundColor(Color.White) .padding(12) .alignItems(VerticalAlign.Top) } } @Preview @Component export struct TutorialView { @State tutorialList: Array<ArticleClass> = [] aboutToAppear(): void { this.getTutorialDataFromJSON() } getTutorialDataFromJSON() { getContext(this).resourceManager.getRawFileContent('TutorialData.json').then(value => { this.tutorialList = JSON.parse(bufferToString(value.buffer)) as ArticleClass[] }) } build() { Column() { Text('入门教程') .fontColor('#182431') .fontSize(16) .fontWeight(500) .fontFamily('HarmonyHeiTi-medium') .textAlign(TextAlign.Start) .padding({ left: 16 }) .margin({ bottom: 8.5 }) List({ space: 12 }) { ForEach(this.tutorialList, (item: ArticleClass) => { ListItem() { TutorialItem({ tutorialItem: item }) } }, (item: ArticleClass) => item.id) } .scrollBar(BarState.Off) .padding({ left: 16, right: 16 }) } .width('100%') .margin({ top: 18 }) .alignItems(HorizontalAlign.Start) } } |
pages
Index.ets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import { TutorialView } from '../view/TutorialView' import { Banner } from '../view/Banner' import { EnablementView } from '../view/EnablementView' @Entry @Component struct Index { @State message: string = '快速入门' build() { Column() { Text(this.message) .fontFamily('HarmonyHeiTi-Bold') .fontSize(24) .fontWeight(700) .lineHeight(33) .width('100%') .textAlign(TextAlign.Start) .margin({ left: 16 }) Scroll() { Column() { Banner() EnablementView() TutorialView() } } .layoutWeight(1) .scrollBar(BarState.Off) .align(Alignment.TopStart) } .height('100%') .width('100%') .backgroundColor('#F1F3F5') } } |