ソースを参照

feat: MVVM 模式

runningwater 6 ヶ月 前
コミット
2fb6a8c18d

+ 15 - 0
entry/src/main/ets/model/ArticleClass.ets

@@ -0,0 +1,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;
+  }
+}

+ 11 - 0
entry/src/main/ets/model/BannerClass.ets

@@ -0,0 +1,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;
+  }
+}

+ 5 - 284
entry/src/main/ets/pages/Index.ets

@@ -1,30 +1,6 @@
-class BannerClass {
-  id: string = '';
-  imageSrc: ResourceStr = '';
-  url: string = ''; // 存储点击跳转的地址
-
-  constructor(id: string, imageSrc: ResourceStr, url: string) {
-    this.id = id;
-    this.imageSrc = imageSrc;
-    this.url = url;
-  }
-}
-
-class ArticleClass {
-  id: string = '';
-  imageSrc: ResourceStr = '';
-  title: string = '';
-  brief: string = '';
-  webUrl: string = '';
-
-  constructor(id: string, imageSrc: ResourceStr, title: string, brief: string, webUrl: string) {
-    this.id = id;
-    this.imageSrc = imageSrc;
-    this.title = title;
-    this.brief = brief;
-    this.webUrl = webUrl;
-  }
-}
+import { Banner } from '../view/Banner';
+import { EnablementView } from '../view/EnablementView';
+import { TutorialView } from '../view/TutorialView';
 
 @Entry
 @Component
@@ -48,263 +24,8 @@ struct Index {
           EnablementView()
           TutorialView()
         }
-      }
-      .layoutWeight(1)
-      .scrollBar(BarState.Off)
-      .align(Alignment.TopStart)
-
-    }
-    .height('100%')
-    .width('100%')
-    .backgroundColor('#F1F3F5')
-  }
-}
-
-@Preview
-@Component
-struct Banner {
-  @State bannerList: Array<BannerClass> = [
-    new BannerClass('pic0', $r('app.media.banner_pic0'),
-      'https://developer.huawei.com/consumer/cn/training/course/video/C101718352529709527'),
-    new BannerClass('pic1', $r('app.media.banner_pic1'), 'https://developer.huawei.com/consumer/cn/'),
-    new BannerClass('pic2', $r('app.media.banner_pic2'), 'https://developer.huawei.com/consumer/cn/deveco-studio/'),
-    new BannerClass('pic3', $r('app.media.banner_pic3'), 'https://developer.huawei.com/consumer/cn/arkts/'),
-    new BannerClass('pic4', $r('app.media.banner_pic4'), 'https://developer.huawei.com/consumer/cn/arkui/'),
-    new BannerClass('pic5', $r('app.media.banner_pic5'), 'https://developer.huawei.com/consumer/cn/sdk'),
-  ];
-
-  build() {
-    Swiper() {
-      ForEach(this.bannerList, (item: BannerClass, index: number) => {
-        Image(item.imageSrc)
-          .objectFit(ImageFit.Contain)
-          .width('100%')
-          .padding({ top: 11, left: 16, right: 16 })
-          .borderRadius(16)
-      }, (item: BannerClass, index: number) => item.id)
-    }
-    .autoPlay(true)
-    .interval(5000)
-    .loop(true)
-    .indicator(
-      new DotIndicator()
-        .color('#1A0000')
-        .selectedColor('#0A59F7'))
-  }
-}
-
-@Preview
-@Component
-export struct EnablementView {
-  @State enablementList: Array<ArticleClass> = [
-    new ArticleClass('1', $r('app.media.enablement_pic1'), 'HarmonyOS第一课',
-      '基于真实的开发场景,提供向导式学习,多维度融合课程等内容,给开发者提供全新的学习体验。',
-      'https://developer.huawei.com/consumer/cn/doc/harmonyos-video-courses/video-tutorials-0000001443535745'),
-    new ArticleClass('2', $r('app.media.enablement_pic2'), '开发指南',
-      '提供系统能力概述、快速入门,用于指导开发者进行场景化的开发。指南涉及到的知识点包括必要的背景知识、符合开发者实际开发场景的操作任务流(开发流程、开发步骤、调测验证)以及常见问题等。',
-      'https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/application-dev-guide-0000001630265101'),
-    new ArticleClass('3', $r('app.media.enablement_pic3'), '最佳实践',
-      '针对新发布特性及热点特性提供详细的技术解析和开发最佳实践。',
-      'https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/topic-architecture-0000001678045510'),
-    new ArticleClass('4', $r('app.media.enablement_pic4'), 'Codelabs',
-      '以教学为目的的代码样例及详细的开发指导,帮助开发者一步步地完成指定场景的应用开发并掌握相关知识。Codelabs将最新的鸿蒙生态应用开发技术与典型场景结合,让开发者快速地掌握开发高质量应用的方法。同时支持互动式操作,通过文字、代码和效果联动为开发者带来更佳的学习体验。',
-      'https://developer.huawei.com/consumer/cn/doc/harmonyos-codelabs/codelabs-0000001443855957'),
-    new ArticleClass('5', $r('app.media.enablement_pic5'), 'Sample',
-      '面向不同类型的开发者提供的鸿蒙生态应用开发优秀实践,每个Sample Code都是一个可运行的工程,为开发者提供实例化的代码参考。',
-      'https://developer.huawei.com/consumer/cn/doc/harmonyos-samples/samples-0000001162414961'),
-    new ArticleClass('6', $r('app.media.enablement_pic6'), 'API参考',
-      '面向开发者提供鸿蒙系统开放接口的全集,供开发者了解具体接口使用方法。API参考详细地描述了每个接口的功能、使用限制、参数名、参数类型、参数含义、取值范围、权限、注意事项、错误码及返回值等。',
-      'https://developer.huawei.com/consumer/cn/doc/harmonyos-references/development-intro-0000001580026066'),
-    new ArticleClass('7', $r('app.media.enablement_pic7'), 'FAQ',
-      '开发者常见问题的总结,开发者可以通过FAQ更高效地解决常见问题。FAQ会持续刷新,及时呈现最新的常见问题。',
-      'https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs/faqs-development-0000001753952202'),
-    new ArticleClass('8', $r('app.media.enablement_pic8'), '开发者论坛', '和其他应用开发者交流技术、共同进步。',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-  ];
-
-  build() {
-    Column() {
-      Text('赋能套件')
-        .fontColor($r('sys.color.font_primary'))
-        .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 })
-    }
-    .margin({ top: 18 })
-    .alignItems(HorizontalAlign.Start)
-    .width('100%')
-  }
-}
-
-@Component
-export struct EnablementItem {
-  @Prop enablementItem: ArticleClass;
-
-  build() {
-    Column() {
-      Image(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 TutorialView {
-  @State tutorialList: Array<ArticleClass> = [
-    new ArticleClass('1', $r('app.media.tutorial_pic1'), 'Step1 环境的搭建',
-      '本篇教程实现了快速入门——一个用于了解和学习HarmonyOS的应用程序。',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-    new ArticleClass('2', $r('app.media.tutorial_pic2'), 'Step2 使用Swiper构建运营广告位',
-      'Swiper组件提供滑动轮播显示的能力。Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-    new ArticleClass('3', $r('app.media.tutorial_pic3'), 'Step3 创建和组合视图',
-      'Item定义子组件相关特征。相关组件支持使用条件渲染、循环渲染、懒加载等方式生成子组件。',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-    new ArticleClass('4', $r('app.media.tutorial_pic4'), 'Step4 网格和列表组建的使用',
-      '网格和列表组件中,当Item达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能,适合用于呈现同类数据类型或数据类型集',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-    new ArticleClass('5', $r('app.media.tutorial_pic5'), 'Step5 应用架构设计基础——MVVM模式',
-      'ArkUI采取MVVM = Model + View + ViewModel模式,将数据与视图绑定在一起,更新数据的时候直接更新视图。',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-    new ArticleClass('6', $r('app.media.tutorial_pic6'), 'Step6 应用架构设计基础——三层架构',
-      '为了更好地适配复杂应用的开发,建议采用三层架构的方式对整个应用的功能进行模块化,实现高内聚、低耦合开发。',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-    new ArticleClass('7', $r('app.media.tutorial_pic7'), 'Step7 ArkWeb页面适配',
-      'ArkWeb(方舟Web)提供了Web组件,用于在应用程序中显示Web页面内容,为开发者提供页面加载、页面交互、页面调试等能力。',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-    new ArticleClass('8', $r('app.media.tutorial_pic8'), 'Step8 数据驱动UI更新', '数据更新的同时会直接驱动UI的改变',
-      'xxx'),
-    new ArticleClass('9', $r('app.media.tutorial_pic9'), 'Step9 设置组件导航',
-      'Navigation组件适用于模块内页面切换,一次开发,多端部署场景。通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式来呈现更好的标题和内容联动效果。',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-    new ArticleClass('10', $r('app.media.tutorial_pic10'), 'Step10 原生智能:AI语音朗读',
-      '文本转语音服务提供将文本信息转换为语音并进行播报的能力,便于用户与设备进行互动,实现实时语音交互,文本播报。',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-    new ArticleClass('11', $r('app.media.tutorial_pic11'), 'Step11 分布式流转',
-      '流转能力打破设备界限,多设备联动,使用户应用程序可分可合、可流转,实现如邮件跨设备编辑、多设备协同健身、多屏游戏等分布式业务。',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-    new ArticleClass('12', $r('app.media.tutorial_pic12'), 'Step12 一次开发,多端部署',
-      '一套代码工程,一次开发上架,多端按需部署。支撑开发者快速高效的开发支持多种终端设备形态的应用,实现对不同设备兼容的同时,提供跨设备的流转、迁移和协同的分布式体验。',
-      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
-  ];
-
-  build() {
-    Column() {
-      Text('入门教程')
-        .fontColor($r('sys.color.font_primary'))
-        .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 })
-    }
-    .margin({ top: 18 })
-    .alignItems(HorizontalAlign.Start)
-    .width('100%')
-  }
-}
-
-@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 })
+      }.layoutWeight(1).scrollBar(BarState.Off).align(Alignment.TopStart)
 
-      Image(this.tutorialItem.imageSrc)
-        .objectFit(ImageFit.Cover)
-        .height(64)
-        .width(108)
-        .borderRadius(16)
-    }
-    .width('100%')
-    .height(88)
-    .borderRadius(16)
-    .backgroundColor(Color.White)
-    .padding(12)
-    .alignItems(VerticalAlign.Top)
+    }.height('100%').width('100%').backgroundColor('#F1F3F5')
   }
 }

+ 7 - 0
entry/src/main/ets/util/BufferUtil.ets

@@ -0,0 +1,7 @@
+import { util } from '@kit.ArkTS';
+
+export function bufferToString(buffer: Uint8Array): string {
+  let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM: true });
+  let resultPut = textDecoder.decodeToString(buffer);
+  return resultPut;
+}

+ 34 - 0
entry/src/main/ets/view/Banner.ets

@@ -0,0 +1,34 @@
+import { BannerClass } from '../model/BannerClass';
+import { bufferToString } from '../util/BufferUtil';
+
+@Preview
+@Component
+export struct Banner {
+  @State bannerList: BannerClass[] = [];
+
+  getBannerDataFromJSON() {
+    this.getUIContext().getHostContext()?.resourceManager.getRawFileContent('BannerData.json')
+      .then(value => {
+        // 获取 buffer 内容并转换为字符串
+        let res: string = bufferToString(value);
+        // 解析为数据结构
+        this.bannerList = JSON.parse(res) as BannerClass[];
+      });
+  }
+
+  aboutToAppear(): void {
+    this.getBannerDataFromJSON();
+  }
+
+  build() {
+    Swiper() {
+      ForEach(this.bannerList, (item: BannerClass) => {
+        Image($r(item.imageSrc))
+          .objectFit(ImageFit.Contain)
+          .width('100%')
+          .padding({ top: 11, left: 16, right: 16 })
+          .borderRadius(16)
+      }, (item: BannerClass) => item.id)
+    }.autoPlay(true).interval(5000).loop(true).indicator(new DotIndicator().color('#1A0000').selectedColor('#0A59F7'))
+  }
+}

+ 82 - 0
entry/src/main/ets/view/EnablementView.ets

@@ -0,0 +1,82 @@
+import { ArticleClass } from '../model/ArticleClass';
+import { bufferToString } from '../util/BufferUtil';
+
+@Preview
+@Component
+export struct EnablementView {
+  @State enablementList: ArticleClass[] = [];
+
+  getEnablementDataFromJSON() {
+    this.getUIContext().getHostContext()?.resourceManager.getRawFileContent("EnablementData.json").then(value => {
+      let res = bufferToString(value);
+
+      this.enablementList = JSON.parse(res) as ArticleClass[]
+    });
+  }
+
+  aboutToAppear(): void {
+    this.getEnablementDataFromJSON();
+  }
+
+  build() {
+    Column() {
+      Text('赋能套件')
+        .fontColor($r('sys.color.font_primary'))
+        .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 })
+    }.margin({ top: 18 }).alignItems(HorizontalAlign.Start).width('100%')
+  }
+}
+
+@Component
+export 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)
+  }
+}

+ 94 - 0
entry/src/main/ets/view/TutorialView.ets

@@ -0,0 +1,94 @@
+import { ArticleClass } from '../model/ArticleClass';
+import { bufferToString } from '../util/BufferUtil';
+
+@Preview
+@Component
+export struct TutorialView {
+  @State tutorialList: ArticleClass[] = [];
+
+  getTutorialDataFromJSON() {
+    this.getUIContext().getHostContext()?.resourceManager.getRawFileContent("TutorialData.json").then(value => {
+      let res = bufferToString(value);
+
+      this.tutorialList = JSON.parse(res) as ArticleClass[]
+    });
+  }
+
+  aboutToAppear(): void {
+    this.getTutorialDataFromJSON();
+  }
+
+  build() {
+    Column() {
+      Text('入门教程')
+        .fontColor($r('sys.color.font_primary'))
+        .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 })
+    }
+    .margin({ top: 18 })
+    .alignItems(HorizontalAlign.Start)
+    .width('100%')
+  }
+}
+
+@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))
+        .objectFit(ImageFit.Cover)
+        .height(64)
+        .width(108)
+        .borderRadius(16)
+    }
+    .width('100%')
+    .height(88)
+    .borderRadius(16)
+    .backgroundColor(Color.White)
+    .padding(12)
+    .alignItems(VerticalAlign.Top)
+  }
+}

+ 32 - 0
entry/src/main/resources/rawfile/BannerData.json

@@ -0,0 +1,32 @@
+[
+  {
+    "id": "pic0",
+    "imageSrc": "app.media.banner_pic0",
+    "url": "https://developer.huawei.com/consumer/cn/training/course/video/C101718352529709527"
+  },
+  {
+    "id": "pic1",
+    "imageSrc": "app.media.banner_pic1",
+    "url": "https://developer.huawei.com/consumer/cn/"
+  },
+  {
+    "id": "pic2",
+    "imageSrc": "app.media.banner_pic2",
+    "url": "https://developer.huawei.com/consumer/cn/deveco-studio/"
+  },
+  {
+    "id": "pic3",
+    "imageSrc": "app.media.banner_pic3",
+    "url": "https://developer.huawei.com/consumer/cn/arkts/"
+  },
+  {
+    "id": "pic4",
+    "imageSrc": "app.media.banner_pic4",
+    "url": "https://developer.huawei.com/consumer/cn/arkui/"
+  },
+  {
+    "id": "pic5",
+    "imageSrc": "app.media.banner_pic5",
+    "url": "https://developer.huawei.com/consumer/cn/sdk"
+  }
+]

+ 58 - 0
entry/src/main/resources/rawfile/EnablementData.json

@@ -0,0 +1,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"
+  }
+]

+ 86 - 0
entry/src/main/resources/rawfile/TutorialData.json

@@ -0,0 +1,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"
+  }
+]