• HarmonyOS从基础到实战-高性能华为在线答题元服务


    最近看到美团、新浪、去哪儿多家互联网企业启动鸿蒙原生应用开发,这个HarmonyOS NEXT越来越引人关注。奈何当前不面向个人开发者开放,但是我们可以尝试下鸿蒙新的应用形态——元服务的开发。
    元服务是基于HarmonyOS提供的一种面向未来的服务提供方式,有独立入口、免安装,以万能卡片等多种呈现形态,可提供一个或多个便捷、轻量化服务。在本文中,我将详细介绍元服务、ArkTS 语言开发以及 DevEco Studio 开发工具的端云一体化开发和低代码开发等方面,并且带大家亲自实战元服务开发-在线答题项目深度体验学习!

    在线答题元服务主要功能:

    1. 接入AGC认证服务,以实现用户登录,展示个人账户信息,在线答题以及积分排行等功能。
    2. 用户可以在应用中进行知识练习,上传自定义题目以丰富题库内容。
    3. 利用华为云服务,实现用户答题展示成绩和排名,增加用户对学习的兴趣。
    4. 使用云数据库存储题目,实现卡片的刷新和页面跳转等功能。

    项目运行演示视频

    一.元服务核心内容

    本文着重介绍元服务元服务轻量化、信息外显的特性,由基础知识学习到项目实战,逐步深入的带大家学习,最后使用元服务技术开发一套高性能,高可用性的在线答题元服务。

    1.1 元服务

    HarmonyOS是一款面向万物互联时代的、全新的分布式操作系统。运行在HarmonyOS的应用分为两种形态:

    • 传统方式的需要安装的应用(即传统概念中的HarmonyOS应用,可简称应用)。
    • 提供特定功能、免安装的应用(即元服务,原名为原子化服务)。

    本文则主要使用元服务形态进行介绍及其开发实战。

    1.1.1元服务的呈现形态

    鸿蒙万能卡片是元服务的主要展现形式之一(其他形式包括语音和图标等)。每个万能卡片都是一种始终可见的元服务或应用,将重要信息以卡片的形式展示在桌面上,通过轻量交互实现服务的便捷访问。
    在这里插入图片描述

    1.1.2 元服务的特点

    ① 免安装,更轻量化地将服务带给用户
    ② 一键服务直达,将用户感兴趣的内容前置、外显
    ③ 跨端转移,多终端设备间无缝流转
    ④ 情景智能卡片推荐,随心定制、更懂用户

    1.2 ArkTS语言

    ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript(简称TS)基本语法风格的基础上,对TS的动态类型特性施加更严格的约束,引入静态类型。同时,提供了声明式UI、状态管理等相应的能力,让开发者可以以更简洁、更自然的方式开发高性能应用。

    1.2.1 ArkTS语言特点

    ArkTS语言通过不断的迭代升级有了许多更新和改进,一年前我第一次接触这个技术,发现很多地方都不完善,相比其他语言(TS,JS)相比有很多不足。但是经过一年的迭代更新,其功能现在已经十分完善且强大。让开发者能够更高效地编写和开发应用程序。
    在这里插入图片描述
    ArkTS提供了简洁自然的声明式语法、组件化机制、数据-UI自动关联等能力,实现了贴近自然语言,书写效率更高的编程方式,为开发者带来易学、易懂、极简开发的优质体验。
    在使用ArkTS语言开发应用时,状态管理是一个重要的概念。状态管理是指管理应用中的各种状态,包括组件状态、全局状态等。状态管理可以帮助开发者更好地组织和管理应用中的数据,使得应用更加稳定和高效。ArkTS提供了多维度的状态管理机制,可以在ArkUI开发框架中使用。和UI相关联的数据,不仅可以在组件内使用,还可以在不同组件层级间传递,比如父子组件之间、爷孙组件之间,也可以是应用全局范围内的传递。

    1.2.2 能力扩展

    ArkTS在TS的基础上主要扩展了如下能力:

    • 基本语法:ArkTS定义了声明式UI描述、自定义组件和动态扩展UI元素的能力,再配合ArkUI开发框架中的系统组件及其相关的事件方法、属性方法等共同构成了UI开发的主体。
    • 状态管理:ArkTS提供了多维度的状态管理机制。在UI开发框架中,与UI相关联的数据可以在组件内使用,也可以在不同组件层级间传递,比如父子组件之间、爷孙组件之间,还可以在应用全局范围内传递或跨设备传递。另外,从数据的传递形式来看,可分为只读的单向传递和可变更的双向传递。开发者可以灵活的利用这些能力来实现数据和UI的联动。
    • 渲染控制:ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态,渲染对应状态下的UI内容。循环渲染可从数据源中迭代获取数据,并在每次迭代过程中创建相应的组件。数据懒加载从数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。

    1.3 DevEco Studio开发工具

    DevEco Studio 3.1配套支持HarmonyOS 3.1版本及以上的应用及服务开发,提供了代码智能编辑、低代码开发、双向预览等功能,以及轻量构建工具DevEco Hvigor 、本地模拟器,持续提升应用及服务开发效率。
    官方下载地址:HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者

    1.3.1低代码开发

    HarmonyOS低代码,有丰富的UI界面编辑功能,例如基于图形化的自由拖拽、数据的参数化配置等,通过可视化界面开发方式快速构建布局,可有效降低用户的时间成本和提升用户构建UI界面的效率。我们来一起体验一下:
    只需在创建新项目时打开低代码按钮(Enable Super Visual)即可:
    在这里插入图片描述
    创建项目之后,我们只需拖动组件到可视化区域即可,我们需要了解下面的工作区功能如下:

    • UI Control:UI控件栏,可以将相应的组件选中并拖动到画布(Canvas)中,实现控件的添加。
    • Component Tree:组件树,在低代码开发界面中,开发者可以直观地看到组件的层级结构、摘要信息以及错误提示。开发者可以通过选中组件树中的组件(画布中对应的组件被同步选中),实现画布内组件的快速定位;单击组件后的或图标,可以隐藏/显示相应的组件。
    • Panel:功能面板,包括常用的画布缩小放大、撤销、显示/隐藏组件虚拟边框、设备切换、明暗模式切换、Media query切换、可视化布局界面一键转换为hml和css文件等。
    • Canvas:画布,开发者可在此区域对组件进行拖拽、拉伸等可视化操作,构建UI界面布局效果。
    • Attributes & Styles:属性样式栏,选中画布中的相应组件后,在右侧属性样式栏可以对该组件的属性样式进行配置。
      我们可以利用可视化来做各种各样的前端页面,这大大的降低了我们的工作量,下面则是一个可视化拖动的效果页面,具体的内容我们则可以到低代码开发文档中进行深度学习。
      在这里插入图片描述

    1.3.2端云一体化开发

    端云一体化开发是DevEco Studio的一个新特性,它允许开发者在本地和云端之间无缝地开发和调试应用程序。通过端云一体化开发,开发者可以更加高效地使用云计算资源,同时也可以在本地快速测试和调试代码。让我们一起体验一下端云一体化开发的魅力。
    在这里插入图片描述
    端云一体化开发基本流程如下:
    创建云函数->调试云函数->云函数与应用程序的通信
    1.创建云函数:在DevEco Studio中,开发者可以轻松地创建和管理云函数。云函数是一段运行在云端的代码,它可以与应用程序进行通信,执行一些需要在云端完成的任务。通过创建云函数,开发者可以利用云计算的强大能力,同时也可以在本地快速测试和调试代码。
    2.调试云函数:在DevEco Studio中,开发者可以使用调试器来调试云函数。调试器允许开发者在本地模拟云函数的运行环境,并在代码中加入断点来进行调试。这使得开发者可以更加轻松地发现和解决问题,提高了开发效率。
    3.云函数与应用程序的通信:在端云一体化开发中,云函数与应用程序之间的通信是非常重要的。DevEco Studio提供了一些工具来帮助开发者实现这种通信。例如,开发者可以使用HTTP或WebSocket协议来与云函数进行通信,也可以使用华为提供的云服务SDK来进行更高级的通信操作。这些工具使得开发者可以更加轻松地实现云函数与应用程序之间的交互,提高了开发效率。
    端云一体化开发相比大家在学习生涯中都有听说,下面就是 HarmonyOS端云一体化开发相比传统开发的优势,大家对比观看就可以发现其优势巨大。集成端云一体化组件后,进行简单配置即可向应用用户提供登录、支付等多种功能。
    在这里插入图片描述

    二.项目云端配置

    2.1 AppGallery Connect服务创建

    AppGallery Connect(以下简称AGC)是华为应用市场推出的应用一站式服务平台,致力于为开发者提供应用创意、开发、分发、运营、分析全生命周期服务,构建全场景智慧化的应用生态。
    在这里插入图片描述
    1.我们需要进入AppGallery Connect服务中心,创建新的项目,并且填入项目名称。
    在这里插入图片描述
    2.进入如下页面,并在Serverless里,找到手机号码,将其设置为启用状态。
    在这里插入图片描述
    在这里插入图片描述
    3.关于SDK配置,因为我们是云端一体化项目,不需要我们额外配置SDK,在创建项目时会自动配置。
    4.到我的应用,创建对应的应用,如下:
    在这里插入图片描述
    需要注意:软件包类型选择HarmonyOS应用,是否元服务选择是。
    5.到Serverless里开通创建云函数和云数据库,如下图。这样提前开通的好处是后续无需更新开通后的配置文件,对新手极为友好。
    在这里插入图片描述

    三.项目环境本地搭建

    提前做完云端配置后,对于项目环境本地搭建较为容易。

    3.1 创建端云一体化元服务项目

    1.只需按下面选择对应的项目模板进行创建。
    在这里插入图片描述
    2.创建项目名称为:arkTSDemo(这是我的案例名称,按照华为包命名规范自行起名即可)。
    注意:需要和上文中的云端创建包名相同,否则会出现下面检测不到的情况,只需要检查包名是否匹配即可解决。
    在这里插入图片描述
    填写对应的参数要求,并且添加到刚刚创建的项目中去。
    在这里插入图片描述
    3.完成上面该有的配置之后,我们再返回到 DevEco Studio,就可以看到我们刚刚创建的。
    在这里插入图片描述
    点击finsh之后我们创建项目,耐心等待配置和自动下载所需资源包即可。
    4.我们的设置SDK也是无需手动配置的,我们的云端一体化创建会帮我们自动的创建好所需的文件和配置,为我们节省了大量的步骤。
    5.创建项目,等待依赖配置完成即可开始我们本次的项目实战了。
    在这里插入图片描述

    四.元服务实战-在线答题

    4.1 项目结构

    我们项目结构如下图所示:
    1.entryability:主应用的Ability
    2.Entnyformability:卡片的Ability
    3.Models:从云数据库导出的数据类型
    4.Pages:页面代码文件夹
    5.Widget->Pages:卡片页面文件夹
    6.rawfile下的俩个文件:
    ①agconnect-services.json:用于连接severless的配置信息
    ②schema.json:云端配置信息
    在这里插入图片描述

    4.2 项目开发计划

    项目接入AGC认证服务用于登录,包含展示个人账号信息的页面、在线答题页面、积分排行页面,用户可以在应用上进行知识练习,随时随地的巩固已学的知识,支持用户自己上传题目,不断完善题库丰富度,构建多元化题库。利用华为云服务提供的高性能,高可用性云服务,可以轻松实现,用户答题展示成绩和进度,根据用户最高成绩进行排行,显示用户的排名,增加用户对学习的兴趣,可以使用元服务卡片展示用户的成绩排名或者成绩和进度均可。
    1.构建优美页面
    2.使用云数据库存储题目,通过云数据库接口进行查询。
    3.桌面卡片的刷新事件依赖于postCardAction接口的message事件。
    4.点击跳转应用使用postCardAction接口的router事件。
    5.FormAbility和应用页面点击后刷新卡片的功能使用formProvider.updateForm接口。

    4.3 登录页面构建

    1.引用部分依赖如下:

    import router from '@ohos.router'
    import prompt from '@ohos.prompt'
    import promptAction from '@ohos.promptAction'
    import {Login, AuthMode} from "@ohos/agconnect-auth-component";
    
    • 1
    • 2
    • 3
    • 4

    2.核心代码(已去特定项目链接块代码,展示供大家直接使用的本页通用核心代码)

    Login({
      modes: [AuthMode.PHONE_VERIFY_CODE, AuthMode.MAIL_VERIFY_CODE],
      onSuccess: (user) => {
        console.log('用户信息:', user.getPhone());
        this.phone=String(user.getPhone());
        router.replaceUrl({
          url: "page/homepage",
          params: {
            name: this.phone
          }
        })
    
      }
    
    }){
      Row() {
        Button('第三方登陆')
          .width("140vp")
          .height("80vp")
          .fontSize(20)
          .margin({
            bottom: 40,
            top: 60,
            right: 20
          })
        Button('立即注册')
          .width("140vp")
          .height("80vp")
          .fontSize(20)
          .margin({
            bottom: 40,
            top: 60,
          })
      }
      Image($r("app.media.logo")).width(80)
    
    • 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

    页面代码功能解释:

    • 导入所需的模块和组件,包括路由 (router)、提示 (prompt)、提示操作 (promptAction) 以及身份验证相关的组件 (Login, AuthMode)。
    • 定义一个名为 LoginPage 的页面组件,用于用户登录。
    • 在 LoginPage 中定义了一些状态 (@State),包括密码 (password)、用户名 (username) 以及电话号码 (phone),用于存储用户输入的信息。
    • 在 build 方法中,创建了页面的布局,包括标题、用户名输入框、密码输入框、忘记密码链接和登录按钮。
    • 当点击登录按钮时,检查用户名和密码是否为空。如果为空,使用路由将用户重定向到 “page/hello” 页面,并传递用户名参数。否则,显示错误提示。
    • 使用身份验证组件 (Login) 提供了第三方登录的选项,当用户成功登录后,将用户的手机号码获取并重定向到 “page/homepage” 页面,同时传递手机号码参数。
    • 页面布局中还包含了第三方登录按钮和立即注册按钮,以及应用的标志图标。
      页面预览效果:
      在这里插入图片描述

    4.4 首页功能构建

    首页是一个包含多个选项卡的页面,详细功能内容如下:

    • 导入所需的模块和组件,包括路由 (router)、提示操作 (promptAction)、Web视图 (web_webview) 和网络请求 (http)。
    • 在 Index 组件中,定义了一些状态 (@State),包括从路由获取的参数 (paramsFromIndex)、播放器数据 (playerData)、当前页数 (mCurrentPage),以及一些其他控制器和资源。
    • 在 build 方法中,创建了一个包含多个选项卡的页面,每个选项卡代表不同的内容。
    • 页面的第一个选项卡包含了一些图片、文字和按钮,以及一个用于观看视频的 Video 组件。还有一个按钮,当点击时会触发 HTTP 请求,获取排行榜数据,并在获取数据后跳转到另一个页面显示排行榜。
    • 页面的第二个选项卡包含了一个视频播放器,用户可以点击按钮来开始播放视频或切换到下一个视频。
    • 页面的第三个选项卡包含了一些个人信息和操作,包括退出登录、题目上传、通知和排行榜。用户可以点击这些操作来执行相应的功能。
    • 使用 Tabs 组件创建了包含选项卡的布局,并在每个选项卡中定义了不同的内容。
      在这里插入图片描述
      核心代码1:
    Tabs({ barPosition: BarPosition.End, controller: this.mTabController }) {
      TabContent() {
        // ... 选项卡1的内容
      }
      .tabBar(this.TabBuilder(0));
      // TabContent2 和 TabContent3 同样方式创建
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    链接云端数据库关键代码

    mport formInfo from '@ohos.app.form.formInfo';
    import formBindingData from '@ohos.app.form.formBindingData';
    import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
    import formProvider from '@ohos.app.form.formProvider';
    import agconnect from '@hw-agconnect/api-ohos';
    import { AGConnectCloudDB, CloudDBZone, CloudDBZoneConfig, CloudDBZoneQuery } from '@hw-agconnect/database-ohos';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.5 答题页面构建

    答题页面是许多应用程序中的关键组成部分,尤其是在教育、娱乐和培训应用中。构建一个功能强大的答题页面,以提供用户友好的答题体验。
    页面设计需满足以下要求:

    • 动态内容展示:页面可以动态显示多个问题和答案选项,根据用户的选择和进度更新内容。
    • 状态管理:使用@State装饰器声明了多个状态属性,用于存储题目、答案、用户选择的答案、解析等信息。这有助于管理和更新页面的状态。
    • 用户交互:用户可以点击答案选项按钮来选择答案,并根据答案的正确与否进行相应的交互反馈。
    • 页面导航:提供了页面导航功能,用户可以在答题完成后返回到主页。
    • 动态解析显示:可以显示答案的解析,用户可以点击按钮来查看问题的解释。
    • 灵活的页面布局:通过Column、Row、Button等组件来构建页面布局,提供了灵活性和可定制性。
    • 按钮样式和交互设计:根据用户的选择状态,按钮的颜色会改变,以提供视觉反馈。
    • 清晰的代码结构:代码结构清晰,使用了注释来解释各个部分的功能,便于理解和维护。
      核心代码:
      @State paramsFromIndex: object = router.getParams()
      @State currentQuestionIndex: number = 0;
      // @State any_go: Resource = $r('app.profile.timu')
      // @State questions: string[] = dati
      @State questions: string[] = this.paramsFromIndex?.['questions']
      @State answers: string[][] =  this.paramsFromIndex?.['answers']
      @State correctAnswers: string[] = this.paramsFromIndex?.['correctAnswers']
      @State explanations: string[] = this.paramsFromIndex?.['explanations'] // 每个问题的解析
      @State selectedAnswer: string = '';
      @State selectedAnswerList: string[] = [];   //用于记录选过的答案
      @State selectedscore: number = 0;
      @State showExplanation: boolean = false; // 用于控制是否显示解析
      @State ende: boolean = false; // 用于控制是否结束
      onNextQuestion() {
        const nextIndex = this.currentQuestionIndex + 1;
        if (nextIndex < this.questions.length) {
          this.currentQuestionIndex = nextIndex;
          this.selectedAnswer = '';
          this.showExplanation = false; // 清空显示解析状态
          this.ende=false;
        } else {
          this.ende=true;
          console.info("------点击了网络请求")
                    extraData: {
                'prapoints': this.selectedscore,
                'userid':3,
                'Numberquestions':this.questions.length
              },
              connectTimeout: 60000, // 可选,默认为60s
              readTimeout: 60000, // 可选,默认为60s
            }, (err, data) => {
    
            if (!err) {
              // data.result为http响应内容,可根据业务需要进行解析
              // @ts-ignore
              const response = JSON.parse(data.result);
              console.info('Result:' + response);
    
            } else {
              console.info('error:' + JSON.stringify(err));
              // 该请求不再使用,调用destroy方法主动销毁。
              httpRequest.destroy();
            }
          }
          );
          AlertDialog.show({
            title: '答题完成',
            message: '恭喜您完成答题!本次成绩:' + this.selectedscore,
          });
        }
      }
    
    • 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

    效果展示
    在这里插入图片描述

    4.5.6 答题卡片页面

    核心代码:

    onNextQuestion() {
      const nextIndex = this.currentQuestionIndex + 1;
      if (nextIndex < this.questions.length) {
        this.currentQuestionIndex = nextIndex;
        this.selectedAnswer = '';
        this.showExplanation = false; // 清空显示解析状态
        this.ende=false;
      } else {
        this.ende=true;
      }
    }
    
    .onClick(() => {
      postCardAction(this, {
        "action": this.ACTION_TYPE,
        "abilityName": this.ABILITY_NAME,
        "params": {
          "message": this.MESSAGE
        }
      });
    })
    
    .onClick(() => {
      this.selectedAnswer = answer;
      this.showExplanation = true; // 显示解析
      this.selectedAnswerList[this.currentQuestionIndex] = answer;
      if (String(index + 1) == this.correctAnswers[this.currentQuestionIndex]) {
        this.selectedscore = this.selectedscore + 1;
      }
    }
    
    
    • 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

    效果展示
    在这里插入图片描述

    4.6 排行榜页面构建

    排行榜页面在应用中起着至关重要的作用,它可以展示用户之间的比赛成绩、竞争和表现。无论是游戏、学习应用还是社交媒体平台,排行榜页面都具有广泛的应用。
    在这里插入图片描述
    核心代码:

    import router from '@ohos.router';
    @Entry
    @Component
    struct LeaderboardPage {
      // 玩家数据数组,每个元素包含玩家姓名和分数
    
      @State paramsFromIndex: object = router.getParams()
      @State playerData: string[][] = this.paramsFromIndex?.['playerData']
    
      build() {
    
        Column() {
          Row() {
            Button("<")
              .width("68.78vp")
              .height("46.26vp")
              // .margin({ left: -60 })
              .fontColor("#fffff")
              .type(ButtonType.Circle)
              .fontSize("27fp")
              .onClick(() => {
                router.replaceUrl({
                  url: "page/homepage",
                  params: {
                    name: this.paramsFromIndex?.['name']
                  }
                })
              });
    
            Text("排行榜")
              .width("80%")
              .height("60vp")
              .fontColor("#0654ef")
              .textAlign(TextAlign.Center)
              .fontSize("30fp");
          }
    
          Column() {
            Image($r('app.media.pai'))
              .width("350.42vp")
              .height("189.02vp")
              .margin({
                top:10,
                bottom:20
              })
          }
          Row() {
    
            Text("   姓名")
              .width("45%")
              .fontSize("20fp")
              .fontColor(Color.Blue); // 可以调整表头的样式
    
            Text("成绩")
              .width("35%")
              .fontSize("20fp")
              .fontColor(Color.Blue);
    
            Text("操作")
              .width("35%")
              .fontSize("20fp")
              .fontColor(Color.Blue);
          }
          // .width("50%")
          // 遍历玩家数据数组,创建玩家条目
          ForEach(this.playerData, (player, index) => {
            Row() {
              Text(`${index + 1}.`)
                .width("10%")
                .fontSize("18fp");
    
              Text(player[0]) // 玩家姓名
                .width("30%")
                .fontSize("18fp");
    
              Text(`得分: ${player[1]}`) // 玩家得分
                .width("40%")
                .fontSize("18fp");
    
              Text("查看")
                .width("20%")
                .fontColor(Color.Red)
                .fontSize("18fp")
                .onClick(() => {
                  // this.onCreate();
                  // this.onCreate()
                  // 在此处理查看详情的逻辑
                  AlertDialog.show({
                    title: "查看",
                    message: `姓名: ${player[0]}\n得分: ${player[1]}`,
                  });
                  // console.error('JSON解析错误:', this.playerData2);
                });
    
            }
            .width("95%")
            .margin({ top: '10vp' })
            .margin(10)
          });
        }
        .width('100%')
      }
    }
    
    • 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
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103

    代码总结:
    1.创建 LeaderboardPage 组件,用于显示排行榜数据
    2.定义了一个页面组件,用于显示排行榜数据,并提供了返回按钮和查看按钮等交互功能。排行榜数据来自路由参数,并以表格的形式呈现在页面上。用户可以点击查看按钮来查看玩家的详细信息。

    4.7 题库上传页面构建

    题库上传页面在教育、培训和娱乐应用中扮演着关键角色,它允许用户上传自定义题库,为学习和娱乐提供更多选择。
    在这里插入图片描述
    题库上传页面的核心是题库数据的结构,我们需要设计和存储这些数据,包括问题、答案和其他相关信息。通常,这些数据可以存储在数据库中,以便后续使用。
    在这里插入图片描述

    • 使用OHOS框架:该页面明显是使用OHOS框架构建的,这是一种适用于HarmonyOS操作系统的应用开发框架。通过导入@ohos.router模块,你可以实现页面之间的导航。
    • 页面布局:页面采用嵌套的Column和Row布局,以创建页面的各个元素。这包括按钮、文本、文本输入框、图片等。
    • 路由导航:通过按钮的onClick事件,页面实现了路由导航功能,允许用户返回到主页(“page/homepage”)。
    • 状态属性:页面使用@State装饰器声明了多个状态属性,如message、paramsFromIndex、questions、answers、correctAnswers、explanations、answersflag,这些状态属性用于存储和管理页面的数据。
    • 数据处理:页面包括多个文本输入框,用于输入题目、选项A、选项B、选项C、选项D、答案和解析。每当用户输入文本时,相应的状态属性会更新以保存用户输入的内容。
    • 提交功能:页面的最后部分包括一个"提交"按钮,当用户点击该按钮时,页面使将用户输入的题目、答案、正确答案和解析等数据传递到数据库。
    • 图像元素:页面包括一个图像元素,通过使用Image组件来显示上传图标。图像的大小和位置都有指定的值。
    • 文本元素:页面使用多个文本元素,如"题目上传"、“选项A:”、"选项B:"等,用于标识和指导用户在输入框中输入什么信息。
    • 样式和排版:页面设置了文本的颜色、字体大小、文本对齐等样式属性,以增强页面的可读性和吸引力。
    • 用户交互:通过文本输入框和按钮的交互,用户可以输入题目和答案,以及提交这些数据。
      数据更新:用户输入的数据通过onChange事件处理函数更新到相应的状态属性,这将允许后续的数据处理和提交。
      核心代码:
    @State message: string = 'Hello World'
    @State paramsFromIndex: object = router.getParams()
    @State questions: string[] = this.paramsFromIndex?.['questions']
    @State answers: string[][] =  this.paramsFromIndex?.['answers']
    @State correctAnswers: string[] = this.paramsFromIndex?.['correctAnswers']
    @State explanations: string[] = this.paramsFromIndex?.['explanations'] // 每个问题的解析
    @State answersflag: string[] =  []
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    链接云端数据库关键代码

    mport formInfo from '@ohos.app.form.formInfo';
    import formBindingData from '@ohos.app.form.formBindingData';
    import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
    import formProvider from '@ohos.app.form.formProvider';
    import agconnect from '@hw-agconnect/api-ohos';
    import { AGConnectCloudDB, CloudDBZone, CloudDBZoneConfig, CloudDBZoneQuery } from '@hw-agconnect/database-ohos';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    要点:

    • 确保数据的准确性和格式,以避免上传无效的题库数据。
    • 优化页面性能,特别是在处理大量数据时,以确保页面响应迅速。

    4.8 真机运行

    真机运行必须先继续签名,只需到项目结构中配置即可。
    注意步骤如下:
    1.用数据线连接HarmonyOS4.0版本系统的手机。
    2.打开开发者模式和USB调试
    3.选择文件传输。
    4.继续签名
    5.运行项目到真机
    在这里插入图片描述
    真机运行效果如下:
    在这里插入图片描述

    五、总结

    5.1项目总结

    在本文中,我们介绍了一个关于在线答题应用的项目,其中包括项目结构和开发计划。以下是本文的主要要点:
    项目结构:

    • 项目主要分为主应用的Ability(entryability)、卡片的Ability(Entnyformability)、从云数据库导出的数据类型(Models)以及页面代码文件夹(Pages)等模块。
    • 使用了两个重要的配置文件,分别是agconnect-services.json和schema.json,用于连接serverless服务和云端配置信息。
      项目开发计划:
    • 项目旨在接入AGC认证服务,以实现用户登录,展示个人账户信息,在线答题以及积分排行等功能。
    • 用户可以在应用中进行知识练习,上传自定义题目以丰富题库内容。
      利用华为云服务,实现用户答题展示成绩和排名,增加用户对学习的兴趣。
    • 页面构建重点在于创建优美的页面布局,使用云数据库存储题目,实现卡片的刷新和页面跳转等功能。

    1.登录页面构建:

    • 登录页面使用OHOS框架构建,包括路由导航,文本输入框,按钮等元素。
    • 使用身份验证组件(Login)提供了多种登录方式,成功登录后将用户信息传递并跳转到主页。
      页面布局包含第三方登录按钮和立即注册按钮,以及应用的标志图标。

    2.首页功能构建:

    • 首页包含多个选项卡,分别展示不同内容,如图片、视频播放器、个人信息、退出登录、题目上传和排行榜等功能。
    • 页面使用Tabs组件创建选项卡,数据来自云端数据库,并实现了排行榜的功能。

    3.答题页面构建:

    • 答题页面用于用户进行知识练习,包括动态内容展示、状态管理、用户交互、页面导航等功能。
    • 用户可以选择答案,查看解析,根据答案是否正确进行得分计算,最后提交答题结果。

    4.排行榜页面构建:

    • 排行榜页面用于展示用户之间的比赛成绩和竞争,用户可以查看其他玩家的成绩。
    • 页面使用路由导航,创建排行榜表格,包括玩家姓名、得分和查看按钮。

    5.题库上传页面构建:
    题库上传页面允许用户上传自定义题库,包括问题、答案、正确答案和解析等数据。。

    6.真机运行:
    最后,文章提到了如何在真机上运行应用,包括继续签名和运行项目的步骤。

    总之,本文介绍了一个在线答题应用的项目结构和开发计划,涵盖了各个页面的功能和核心代码,为开发者提供了建立类似应用的指导。

    5.2 元服务总结

    1. 元服务的概念:
      元服务作为HarmonyOS的一个重要概念,具有独立入口、免安装的特点,为用户提供了更轻量化的服务访问方式。通过万能卡片等形态,用户可以更方便地访问重要信息和功能。这种形式使应用更具便捷性,尤其适用于未来的智能设备。
    2. ArkTS语言的优势:
      ArkTS语言是HarmonyOS的应用开发语言,它强调静态类型和声明式UI,这有助于提高代码质量和可维护性。同时,它提供了丰富的状态管理机制,允许在不同组件层级之间传递数据,这是构建复杂应用所必需的。ArkTS的不断迭代和完善,使其成为一种强大的开发语言。
    3. DevEco Studio开发工具的便捷性: DevEco
      Studio是一个功能强大的开发工具,支持HarmonyOS应用和服务的开发。其中,低代码开发功能为开发者提供了可视化界面,使UI开发更加高效。而端云一体化开发则允许开发者在本地和云端之间灵活开发和测试应用。这样的工具可以大大提高开发效率。
    4. 端云一体化开发的优势:
      端云一体化开发为开发者提供了强大的云计算能力,并允许在本地进行代码调试。这使开发者能够更高效地利用云资源,并更轻松地发现和解决问题。此外,与应用程序之间的通信也得到了很好的支持,使得开发更加便捷。

    总的来说,HarmonyOS的元服务、ArkTS语言和DevEco Studio开发工具以及端云一体化开发,为开发者提供了构建现代化、轻量化、高性能应用的便捷方式。这些技术和工具将帮助开发者更好地适应未来的智能设备和服务提供方式。

    六.附录

    元服务介绍
    https://developer.huawei.com/consumer/cn/harmonyos/fa
    ArkTS语言介绍
    https://developer.harmonyos.com/cn/develop/arkts/
    端云一体化开发介绍
    https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/agc-harmonyos-clouddev-overview-0000001443209792-V3
    低代码开发介绍
    https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/ide-low-code-overview-0000001480179573-V3

  • 相关阅读:
    浅析-ES6
    leetCode 229. 多数元素 II + 摩尔投票法 + 进阶 + 优化空间
    内容长度不同的div如何自动对齐展示
    Leetcode刷题详解——移动零
    React Native 环境搭建
    java125-简单异常处理
    LevelDB 学习笔记1:布隆过滤器
    猿创征文|一名大三学生的前端学习之路(真情流露)
    换掉ES!Redis官方搜索引擎来了,性能炸裂!
    一个可操作PPT的.Net开源库
  • 原文地址:https://blog.csdn.net/weixin_52908342/article/details/134467049