🚀前言
最近HarmonyOS NEXT大火,這個純血鴻蒙吸引力了大家的關注。雖然現在還沒面向個人開發者開放,但我們可以基于最新的API9及開發工具來嘗試開發鴻蒙新的應用形態——元服務。來體驗下未來在HarmonyOS NEXT上實現的應用開發。
HarmonyOS是華為公司開發的操作系統,它的設計理念是面向未來的全場景智慧體驗,可在各種設備上運行,包括手機、平板電腦、智能手表、智能音箱等。HarmonyOS采用分布式技術,可以將不同設備之間的計算資源連接起來,實現設備間的協同工作,提高系統的性能和穩定性。此外,HarmonyOS還擁有高度自適應的界面、多屏協同等特性,使用戶能夠在不同設備上實現無縫的體驗。
本文主要是基于手語學習元服務的開發案例:主要的功能有
- 元服務內部功能:
- 1、提供專業手語翻譯老師示范視頻,包括基本手勢、字母表、常用短語等。用戶可以點擊觀看示范并模仿。
- 2、提供類似答題模塊,幫助用戶鞏固所學的手語知識,用戶可以完成答題模塊測試自己的進步。
- 元服務卡片:
- 1、卡片界面展示每日一題,并可以在卡片上進行答題學習
項目實現效果如下:
元服務內部功能視頻:
元服務卡片功能視頻:
🚀一、HarmonyOS元服務簡介
🔎1.什么是元服務
元服務(原名為原子化服務)是HarmonyOS提供的一種面向未來的服務提供方式。它是一種新型應用程序形態,具有獨立入口、免安裝的特點,可以為用戶提供一個或多個便捷服務。
以線上購物為例,傳統購物應用需要先安裝應用,打開應用查找商品,加入購物車,然后完成支付。而通過元服務的方式,可以將購物過程拆分為多個服務,例如“商品瀏覽”、“購物車”、“支付”等,無需安裝應用,通過豐富的入口直達服務頁面。例如,將心儀的商品頁添加到桌面,可以實時掌握商品價格的變動。在秒殺時間點,可以直接進入購物車進行結算。
元服務基于HarmonyOS API開發,為用戶在合適的場景、合適的設備上提供便捷的使用體驗。相比傳統的需要安裝的應用形態,元服務更加輕量,同時提供更豐富的入口和更精準的分發。它為用戶提供了更靈活、更高效的服務方式,提升了用戶體驗和便利性。
🔎2.元服務的獨特價值
元服務的呈現形態之一是鴻蒙萬能卡片,它是元服務最主要的展示方式之一(其他形態包括語音、圖標等)。每一個萬能卡片都是一個在桌面上“永遠打開的”元服務/應用,以卡片的形式展示元服務/應用的重要信息,并通過輕量級的交互行為實現服務的直達。
元服務帶來了體驗上的變革,具體表現在以下幾個方面:
- 免安裝:元服務以更輕量化的方式將服務提供給用戶,無需進行繁瑣的應用安裝過程,節省了用戶的時間和存儲空間。
- 一鍵服務直達:元服務將用戶感興趣的內容前置、外顯,通過一鍵操作即可直接進入所需的服務頁面,提供了更快捷、便利的服務體驗。
- 跨端轉移:元服務支持多終端設備間的無縫流轉,用戶可以在不同的設備上無縫切換使用元服務,提供了更連貫、一致的服務體驗。
- 情景智能卡片推薦:元服務可以根據用戶的需求和偏好進行情景智能卡片推薦,用戶可以隨心定制自己的服務卡片,并根據個人喜好進行個性化設置,從而更好地滿足用戶的需求。
通過以上的變革,元服務為用戶帶來了更輕便、更直觀、更智能的服務體驗,提升了用戶的便利性和滿意度。
🔎3.元服務的應用場景
🦋3.1 負一屏
負一屏旨在提供更快速便捷的信息和服務,采用了宮格設計,將常用服務進行分類,涵蓋了本地生活、智慧出行、購物娛樂、金融理財等多個場景。用戶通過右滑進入發現頁,即可輕松地獲取所需的服務,無需下載繁瑣的App。此外,負一屏還具備實時狀態的新體驗,用戶使用服務后可以隨時查看進度,掌握關鍵節點信息。
🦋3.2 應用市場
打開華為應用市場,點擊“應用”頁簽,進入“元服務”專區發現并使用元服務。
🦋3.3 桌面
用戶可以將元服務的卡片添加到桌面,便可在桌面隨時隨地查看元服務的重要信息,點擊卡片即可直達所需服務。
🦋3.4 碰一碰/掃一掃
用戶首次“碰一碰”或者“掃一掃”識別設備上的NFC標簽,系統引導用戶連接設備,連接成功后,再次“碰一碰”或者“掃一掃”即可直接使用相應的元服務。
🚀二、開發環境搭建
🔎1.DevEco Studio
DevEco Studio是一款專門為鴻蒙(HarmonyOS)系統開發而設計的綜合性開發工具IDE,開發者可以利用該工具進行鴻蒙應用的設計、開發、調試和發布。DevEco Studio集成了代碼編輯器、模擬器、調試工具、圖形用戶界面設計器和應用管理工具等多個功能,方便開發者進行鴻蒙應用的開發與管理。
DevEco Studio支持多語言開發,包括Java、ArkTS、JavaScript等,同時還支持多種開發模式和框架。此外,它還支持多平臺開發,包括手機、平板、智能手表、電視等不同終端設備。
DevEco Studio下載地址:HUAWEI DevEco Studio和SDK下載和升級 | HarmonyOS開發者
安裝完成之后界面:
🔎2.配置環境變量
本文以window系統為例,具體操作步驟如下:
1、通過“設置 > 系統 > 系統信息 > 高級系統設置”進入“系統屬性”頁面的“高級”頁簽,點擊“環境變量”
2、在“系統變量”中添加 HDC_SERVER_PORT和OHOS_HDC_SERVER_PORT 兩個變量,變量值設置為未被占用的端口,例如7036和7037
3、在用戶或者系統的path變量中,添加HDC工具的路徑。
HDC工具路徑為:HarmonyOS SDK安裝目錄/hmscore/{版本號}/toolchains。例如:C:\Users\XXXXX\AppData\Local\Huawei\Sdk\hmscore\3.1.0\toolchains
環境變量配置完成,重啟DevEco Studio。
🔎3.診斷開發環境
1、打開項目,從歡迎頁進入:底部菜單選擇“Help > Diagnose Development Environment”
2、待自動檢查完成。如果有檢查未通過的項目,請根據檢查項的描述和修復建議進行處理
🔎4.下載SDK
1、打開項目,從歡迎頁進入:底部菜單選擇“Configure > Settings”
🚀三、創建元服務項目
🔎1.創建元服務項目的步驟
1、登錄AppGallery Connect, 點擊“我的應用”。
首次進入需要簽協議
2、在“HarmonyOS”頁簽,“類型”選擇“元服務”,可以查看創建的元服務。
🔎2.選擇模板和配置項目屬性
1、打開DevEco Studio,菜單選擇“File > New > Create Project”,創建一個新工程。
2、選擇“Atomic Service”,選擇“Empty Ability”模板,點擊“Next”。
3、配置工程基本信息。
- Project name:設置“myProject”。
- Bundle name:本樣例以“com.huawei.myproject”為例。
- Save location:選擇工程存放路徑。
- Compile SDK:支持API 4~9,本樣例選擇“API 9”。
- Model:應用支持的模式,API Version 4~8只支持FA模式。
- Enable Super Visual:是否使用低代碼開發模式,本樣例不打開此開關。
- Language:開發語言。
- Device type:該工程模板支持的設備類型。本樣例以手機設備為例。
點擊“Finish”,等待工程創建完成,即可進行代碼編寫。
🔎3.編寫代碼和調試運行
1、點擊右側的Previewer工具,預覽頁面效果。
2、新建details.ets頁面
details.ets頁面
@Entry
@Component
struct Details {build() {//Flex容器組件Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {//Text組件Text('我是跳轉頁面').fontSize(60).fontWeight(500)}//容器整體寬高.width('100%').height('100%')}
}
main_pages.json頁面
{"src": ["pages/Index","pages/details"]
}
3、添加跳轉按鈕實現頁面跳轉
index.ets頁面
import router from '@ohos.router'
@Entry
@Component
struct Index {@State message: string = '愚公搬代碼'build() {//Flex容器組件Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {//Text組件Text('愚公搬代碼').fontSize(60).fontWeight(500)//Button組件Button('跳轉下一頁').fontSize(40).fontWeight(500).width(280).height(60)//點擊Button實現頁面跳轉.onClick(() => {console.info("跳轉開始")router.pushUrl({url: 'pages/details' // 目標url}, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');});})}//容器整體寬高.width('100%').height('100%')}
}
🚀四、元服務代碼分析
🔎1.元服務代碼結構介紹
- AppScope中存放應用全局所需要的資源文件。
- entry是應用的主模塊,存放HarmonyOS應用的代碼、資源等。
- oh_modules是工程的依賴包,存放工程依賴的源文件。
- build-profile.json5是工程級配置信息,包括簽名、產品配置等。
- hvigorfile.ts是工程級編譯構建任務腳本,hvigor是基于任務管理機制實現的一款全新的自動化構建工具,主要提供任務注冊編排,工程模型管理、配置管理等核心能力。
- oh-package.json5是工程級依賴配置文件,用于記錄引入包的配置信息。
🦋1.1 AppScope
- element文件夾主要存放公共的字符串、布局文件等資源。
- media存放全局公共的多媒體資源文件。
🦋1.2 entry
- entryability用于當前ability應用邏輯和生命周期管理。
- entryformability用于當前卡片生命周期管理。
- pages存放UI界面相關代碼文件,初始會生成一個Index頁面。
- ohosTest是單元測試目錄。
- build-profile.json5是模塊級配置信息,包括編譯構建配置項。
- hvigorfile.ts文件是模塊級構建腳本。
- oh-package.json5是模塊級依賴配置信息文件。
- resources目錄下存放模塊公共的多媒體、字符串及布局文件等資源,分別存放在element、media文件夾中。
🔎2.開發選型
HarmonyOS 3.1及以上版本支持ArkTS、JS語言和Stage模型和FA模型兩種模型,其中Stage模型為從HarmonyOS 3.1開始新增的模型,將是長期演進的模型。
HarmonyOS中的Stage模型是指應用程序的窗口管理器和圖形引擎。Stage模型包含一個場景(Scene)和多個舞臺(Stage),每個舞臺表示一個窗口。在舞臺上,可以添加多個UI元素(如Button、Label、Image等),通過對UI元素進行布局、組合和交互,實現應用程序的功能。
在HarmonyOS中,通過Stage模型,可以實現窗口管理、多任務處理、圖形渲染和事件處理等功能。同時,Stage與HarmonyOS系統的分層架構緊密結合,可以自動適配不同屏幕、不同分辨率的設備,保證應用程序在各種設備上的兼容性和可用性。
一個應用包含一個或者多個Module,以下是Module與UIAbility組件關系示意圖:
編譯后的示意圖:
🔎3.元服務中常用的API和類
- OHOS::AAFwk::Ability: 這是Ability的基類,提供了啟動、停止和生命周期管理等能力。
- OHOS::AAFwk::Want: 跨應用程序組件之間傳遞的信息,可以指定Intent和Bundle等參數。
- OHOS::AppExecFwk::EventHandler: 用于在Ability生命周期內處理異步任務,支持延遲執行和定時執行。
- OHOS::EventFwk::EventRunner: 用于實現異步事件的執行和處理。
- OHOS::AGP::Window: 應用程序窗口,用于顯示UI界面。
- OHOS::AGP::View: UI界面中的基本控件,如Button、TextView等。
- OHOS::DataAbility::DataAbilityHelper: 數據能力的基礎類,用于管理數據的增刪改查操作。
- OHOS::DistributedSchedule::DistributedSchedulPolicy: 分布式調度策略,用于實現分布式系統的任務調度。
- OHOS::Media::MediaPlayer: 用于播放音頻和視頻文件。
- OHOS::Security::Permission: 權限管理類,用于管理應用程序對系統資源的訪問權限。
🚀五、案例展示:手語猜一猜
🔎1.案例背景
手語學習元服務的案例背景主要是為了幫助人們學習手語,提高對聾人的理解和尊重。聾人由于聽力障礙,無法通過聲音語言進行交流,而手語是聾人交流的主要方式。手語學習元服務通過數字化的方式提供了學習手語的機會,讓更多的人能夠了解手語,學習手語,以便更好地與聾人交流和理解聾人的需求。
隨著社會的不斷發展,聾人的教育和融入社會的問題日益重要。手語學習應用可以提供數字化的手語課程,讓更多的人能夠學習手語,提高對聾人的理解和尊重,促進聾人的教育和融入社會。
手語是一種非常有意義的語言,它不僅可以讓聾人與人進行有效的交流,還可以幫助聽力正常的人了解和尊重聾人的文化和生活習慣。手語學習應用也可以成為一個重要的手語文化傳播平臺,讓更多的人了解和學習手語,促進手語文化的傳播和發展。
🔎2.功能簡介
元服務:
1、提供專業手語翻譯老師示范視頻,包括基本手勢、字母表、常用短語等。用戶可以點擊觀看示范并模仿。
2、提供類似答題模塊,幫助用戶鞏固所學的手語知識,用戶可以完成答題模塊測試自己的進步。
元服務卡片:
1、卡片界面展示每日一題,并可以在卡片上進行答題學習
🔎3.案例實現流程
🦋3.1 內部應用功能
??3.1.1 首頁功能
首頁功能主要包含了4塊功能:每日挑戰、課程、測試、學習記錄
🌈3.1.1.1 每日挑戰
每日挑戰主要的交互有2塊功能:換一換和答題
換一換:主要實現題目和資源的切換(替換題目、替換視頻鏈接)
答題:主要是根據選項遍歷出Button按鈕,在根據按鈕點擊事件判斷點擊的按鈕type等于1則答題正確
源碼片段如下:
Flex({ justifyContent: FlexAlign.SpaceBetween }){Text('每日挑戰').fontSize(20).fontColor('#fff').width('50%')Column() {Flex({ justifyContent: FlexAlign.End }) {Image(this.ic_new).width(20).height(20).margin({right:5})Text('換一批').fontSize(20).fontColor('#fff').onClick(()=>{this.anyArray=[{name:'吃',type:1},{name:'厲害',type:0}]this.videoSrc=$rawfile('quick.mp4')this.previewUri=$r('app.media.quick')})}.width('50%')}
}.padding(10).backgroundColor('#938cf4')Column(){Column(){Flex({justifyContent:FlexAlign.SpaceBetween}){Text('根據視頻所示,選擇正確的答案').fontSize(12).fontColor('#fff')Text('40%的人答錯').fontSize(12).fontColor('#fff')}.padding({top:10,left:10,right:10,bottom:10}).margin({top:0})Video({src: this.videoSrc,previewUri: this.previewUri,currentProgressRate: this.curRate,controller: this.controller}).width('100%').height(180).padding(5).borderRadius(1).margin({top:0,left:10,right:10,bottom:10,})Flex({justifyContent:FlexAlign.SpaceBetween}){ForEach(this.anyArray,(item)=>{Button(item.name,{ type: ButtonType.Normal,}).borderRadius(0).width('45%').backgroundColor('#ff986ec8').onClick(()=>{if(item.type==1){if (this.dialogController != undefined) {this.dialogController.open()this.textValue='答對了'}}else{if (this.dialogController != undefined) {this.dialogController.open()this.textValue='答錯了'}}})})}.margin({top:0,left:10,right:10,bottom:10,})}.backgroundColor('#ffa49fea').margin({top:0,left:10,right:10,bottom:10,}).borderRadius(10)}.backgroundColor('#938cf4')
🌈3.1.1.2 課程
這邊主要是點擊按鈕跳轉到課程頁面一個功能
源碼片段如下:
Column() {Flex({ alignItems: this.alignItems }) {Text('課程').width('50%').fontSize(20).fontWeight(FontWeight.Bold)}.size({width: '90%',}).padding({top:20,left:10,bottom:0})Flex({ justifyContent: FlexAlign.SpaceBetween }) {Text('初級課程,易上手').width('70%').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#c4c2cf')Button('學習').width('30%').backgroundColor('#fecc5b').margin({top:-25,}).onClick(()=>{router.push({ url: 'pages/list' })})}.size({width: '100%', }).padding({ left: 30 ,top:10,right:30,bottom:20},).border({radius:{bottomLeft: 15, bottomRight: 15}})
}.width('90%')
.backgroundColor('#fff')
.borderRadius(15)
.margin(20)
🌈3.1.1.3 測試
這邊主要是點擊按鈕跳轉到測試頁面一個功能
源碼片段如下:
Column() {Flex({ alignItems: this.alignItems }) {Text('課程').width('50%').fontSize(20).fontWeight(FontWeight.Bold)}.size({width: '90%',}).padding({top:20,left:10,bottom:0})Flex({ justifyContent: FlexAlign.SpaceBetween }) {Text('初級課程,易上手').width('70%').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#c4c2cf')Button('學習').width('30%').backgroundColor('#fecc5b').margin({top:-25,}).onClick(()=>{router.push({ url: 'pages/list' })})}.size({width: '100%', }).padding({ left: 30 ,top:10,right:30,bottom:20},).border({radius:{bottomLeft: 15, bottomRight: 15}})
}.width('90%')
.backgroundColor('#fff')
.borderRadius(15)
.margin(20)
🌈3.1.1.4 學習記錄
這邊主要是基于組件的形式在界面展示,功能點主要有:時間數據、學習課程數
- 時間數據:已當前時間自動更新
- 學習課程數:來源于已學課程的本地存儲數據(存儲來源在課程學習界面)
源碼片段如下:
PersistentStorage.PersistProp('course', 0);let date = new Date()
let time = date.getFullYear() + "年" + (date.getMonth() + 1) + "月" + date.getDate() + "日"
console.log(time);
@Component
export default struct studyCollect {alignItems : number = 0// @State timeDate:string = date@StorageLink('course') course: number = 0@State dayTime:string=time;build() {Column() {Flex({ alignItems: this.alignItems }) {Text('學習記錄').width('50%').fontSize(20).fontWeight(FontWeight.Bold)Text(` ${this.dayTime}`).width('50%').height(30).textAlign(TextAlign.End)}.size({width: '90%', height: 50}).margin({top:10}).padding(10)Flex({ alignItems: this.alignItems }) {Text(`已學${this.course}課程`).width('50%').height(20).fontSize(16).fontWeight(FontWeight.Bold).fontColor('#fff')Text(`${this.course}分鐘`).width('50%').height(20).textAlign(TextAlign.End).fontColor('#fff')}.size({width: '100%', height: 50}).padding({ left: 40 ,top:15,right:40,},).border({radius:{bottomLeft: 15, bottomRight: 15}}).backgroundColor('#938cf4')}.width('90%').backgroundColor('#fff').borderRadius(15).margin({top:5})}
}
??3.1.2 課程功能
課程主頁面主要是課程信息展示和跳轉到具體詳情頁面
源碼片段如下:
import router from '@ohos.router';import { arrImage } from '../common/json'
@Entry
@Component
struct list {scroller: Scroller = new Scroller();@State arrImage: Object[]=arrImagebuild() {Scroll(this.scroller) {Column() {Column({ space: 5 }) {Text('初級課程').fontSize(20).fontColor('#fff').width('90%').padding(10).backgroundColor('')Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.SpaceBetween }) {ForEach(this.arrImage, (item) => {Column() {Image(item.image).width('100%').height(120)Text(item.name).lineHeight(30)}.width('45%').height(150).backgroundColor(0xF5DEB3).margin(5).onClick(()=>{router.pushUrl({url:'pages/details',params:{text:item.name,image:item.image,video:item.video}})})})}.width('100%').padding(10).backgroundColor(0xAFEEEE)}.width('100%').margin({ top: 5 })}.width('100%').backgroundColor('#938cf4')}.backgroundColor(0xDCDCDC).scrollable(ScrollDirection.Vertical) // 滾動方向縱向.scrollBar(BarState.On) // 滾動條常駐顯示.scrollBarColor(Color.Gray) // 滾動條顏色.scrollBarWidth(5) // 滾動條寬度.edgeEffect(EdgeEffect.Spring) // 滾動到邊沿后回彈}
}
🌈3.1.2.1 課程詳情頁
功能點主要有:路由數據、客戶對課程的狀態信息
- 路由數據:手語答案、手語視頻地址
- 客戶對課程的狀態信息:點贊、收藏、轉發相關狀態變更
源碼片段如下:
import router from '@ohos.router'
import promptAction from '@ohos.promptAction'import { CommonTitleBar } from '../common/CommonTitleBar';@Entry
@Component
struct Index {@StorageLink('course') course: number = 0// @State good:Resource=$r('app.media.icon_good');@State goodStatus:boolean=true@State goodNumber:number=0@State startStatus:boolean=true@State startNumber:number=0@State shareStatus:boolean=true@State shareNumber:number=0@State text: string = router.getParams()['text']@State previewUri: Resource = router.getParams()['image']@State videoSrc: Resource = router.getParams()['video']@State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_Xcontroller: VideoController = new VideoController()alignItems : number = 0build() {Column(){// CommonTitleBar({attribute: {// bg_color: '#ff2ad4b2',// close_text: '返回',// closeCallback: () => {//// },// title_text: '標題',// menuCallback: () => {//// }// }})Column(){Column(){Video({src: this.videoSrc,previewUri: this.previewUri,currentProgressRate: this.curRate,controller: this.controller}).width('100%').height(180).padding(10).borderRadius(10).onFinish(() => {this.course += 1;console.info('onFinish')})}Flex(){Text('當前示例:').fontSize(24)Text(`${this.text}`).fontSize(24)}.padding(10)Flex({}){Flex(){Image(this.goodStatus ? $r("app.media.icon_good"):$r("app.media.active_icon_good")).width(24).height(24)Text(`${this.goodNumber}`).height(25)}.width('20%').onClick(()=>{this.goodStatus=!this.goodStatus;this.goodStatus ? this.goodNumber--:this.goodNumber++;promptAction.showToast({message: this.goodStatus ? '取消點贊' :'點贊成功',duration: 2000,});})Flex(){Image(this.startStatus ? $r("app.media.icon_star"):$r("app.media.active_icon_star")).width(24).height(24)Text(`${this.startNumber}`).height(25)}.width('20%').onClick(()=>{this.startStatus=!this.startStatus;this.startStatus ? this.startNumber--:this.startNumber++;promptAction.showToast({message: this.startStatus ? '取消收藏' :'收藏成功',duration: 2000,});})Flex(){Image(this.shareStatus ? $r("app.media.icon_share"):$r("app.media.active_icon_share")).width(24).height(24)Text(`${this.shareNumber}`).height(25)}.width('20%').onClick(()=>{this.shareStatus=!this.shareStatus;this.shareStatus ? this.shareNumber--:this.shareNumber++;promptAction.showToast({message: this.shareStatus ? '取消轉發' :'轉發成功',duration: 2000,});})}.padding(10)}}//容器整體寬高.width('100%').height('100%').backgroundColor('#ff0f2ff')}
}
??3.1.3 測試功能
測試功能頁面主要功能是從json的題庫取出10題,如果答題正確會自動切換到下一題。
源碼片段如下:
import router from '@ohos.router'import promptAction from '@ohos.promptAction'
import { arrImage } from '../common/json'
@Entry
@Component
struct Index {@State onActive : number = 1@State arrImage: Object[]=arrImage@State videoSrc: Resource = $rawfile('hello.mp4')@State previewUri: Resource = $r("app.media.hello")@State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_Xcontroller: VideoController = new VideoController()alignItems : number = 0@State message: string = '手語猜猜看'@State studyName: string = '手語閱覽'@State collectName: string = '手語挑戰'@State testName: string = '測試'@State arr: string[] =['你好','出生','愛','晚飯','中午','明天']build() {Column(){Column(){Flex({alignItems:ItemAlign.Center,justifyContent:FlexAlign.Center}){// Text(`${this.arrImage[this.onActive]['name']}`)Text(`${this.onActive}`).fontSize(28)Text('/').fontSize(28)Text(`${this.arrImage.length}`).fontSize(28)}.margin(10)Column(){Video({src: this.arrImage[this.onActive-1]['video'],previewUri: this.arrImage[this.onActive-1]['image'],currentProgressRate: this.curRate,controller: this.controller}).width('100%').height(180).margin({top:0,bottom:0,})}Column({}){Text('在下列選項中選擇正確答案?').width('100%').padding(10).fontSize(20)}.backgroundColor('#fff')Flex({wrap: FlexWrap.Wrap }){ForEach(this.arrImage[this.onActive-1]['answer'],(item:string)=>{Button(item,{ type: ButtonType.Normal,}).margin(5).borderRadius(5).onClick(() => {console.log(item)if(this.onActive>=this.arrImage.length){promptAction.showToast({message: '闖關已結束',duration: 2000,});router.back({url:'pages/index'});return false;}if(item==this.arrImage[this.onActive-1]['name']){promptAction.showToast({message: '答對了,請繼續下一題',duration: 2000,});this.onActive=this.onActive+1;}else{promptAction.showToast({message: '答錯了',duration: 2000,});}})})}.padding(10)}}//容器整體寬高.width('100%').height('100%').backgroundColor('#ff0f2ff')}
}
🦋3.2 卡片功能
這邊和每日挑戰功能類似,主要多了些動畫效果,卡片主要的交互有2塊功能:換一換和答題
- 換一換:主要實現題目和資源的切換(替換題目、替換視頻鏈接)
- 答題:主要是根據選項遍歷出Button按鈕,在根據按鈕點擊事件判斷點擊的按鈕type等于1則答題正確
源碼片段如下:
@Entry
@Component
struct WidgetCard {@State onActive:number=0@State arrImage: Object[] = [{name:'你好',image:$r("app.media.hello"),content:'一手食指指向對方。一手握拳,向上伸出拇指。',video:$rawfile('hello.mp4'),anyArray:[{name:'你好',type:1},{name:'謝謝',type:0}]},{name:'謝謝',image:$r('app.media.thank'),content:'一手伸出拇指,彎曲兩下,表示向人感謝。',video:$rawfile('thank.mp4'),anyArray:[{name:'不好',type:0},{name:'謝謝',type:1}]},{name:'愛',image:$r('app.media.love'),content:'一手輕輕撫摩另一手拇指指背,表示一種“憐愛”的感情',video:$rawfile('love.mp4'),anyArray:[{name:'沒有',type:0},{name:'愛',type:1}]},{name:'喜歡',image:$r('app.media.live'),video:$rawfile('like.mp4'),content:'一手拇、食指微曲,指尖抵于頜下,頭微微點動一下。 ',anyArray:[{name:'沒有',type:0},{name:'喜歡',type:1}]},{name:'不喜歡',image:$r('app.media.dislike'),video:$rawfile('dislike.mp4'),content:'一手伸直,左右擺動幾下。 一手拇、食指微曲,指尖抵于頜下,頭微微點動一下。 ',anyArray:[{name:'好暈',type:0},{name:'不喜歡',type:1}]},{name:'飯',image:$r('app.media.eat'),video:$rawfile('eat.mp4'),content:'(一)一手拇、食指相對,中間留有米粒大小距離。(二)一手伸食、中指象征筷子,作吃飯動作。',anyArray:[{name:'可愛',type:0},{name:'飯',type:1}]},{name:'快',image:$r('app.media.quick'),video:$rawfile('quick.mp4'),content:'一手拇、食指相捏,很快地從一側向另一側作快速揮動,象征物體運動速度很快。',anyArray:[{name:'慢',type:0},{name:'快',type:1}]},{name:'慢',image:$r('app.media.slow'),video:$rawfile('show.mp4'),content:'一手掌心向下,慢慢地上下微動幾下,象征物體運動速度緩慢。',anyArray:[{name:'去',type:0},{name:'慢',type:1}]},{name:'沒關系',image:$r('app.media.matter'),video:$rawfile('matter.mp4'),content:'一手拇、食、中指捻動,連續幾次。 兩手拇、食指搭成圓圈,互相套環。 ',anyArray:[{name:'人類',type:0},{name:'沒關系',type:1}]},{name:'厲害',image:$r('app.media.powerful'),video:$rawfile('powerful.mp4'),content:'一手打手指字母“L”的指式,并繞臉部轉一圈。同時面部作出嚴厲的表情。 ',anyArray:[{name:'好帥',type:0},{name:'厲害',type:1}]},];/** The max lines.*/readonly MAX_LINES: number = 1;/** The action type.*/readonly ACTION_TYPE: string = 'router';/** The message.*/readonly MESSAGE: string = 'add detail';/** The ability name.*/readonly ABILITY_NAME: string = 'EntryAbility';/** The with percentage setting.*/readonly FULL_WIDTH_PERCENT: string = '100%';/** The height percentage setting.*/readonly FULL_HEIGHT_PERCENT: string = '100%';@State opacityAngle: number = 0.8@State mainFlag: boolean = false;@State flag: boolean = true;build() {Stack() {if(this.flag){Image(this.arrImage[this.onActive]['image']).width(this.FULL_WIDTH_PERCENT).height(this.FULL_HEIGHT_PERCENT).objectFit(ImageFit.Cover).opacity(this.opacityAngle).transition({ type: TransitionType.Insert, translate: { x: 0, y: 0 } }).transition({ type: TransitionType.Delete, opacity: 0, scale: { x: 0, y: 0 } })}else{Image(this.arrImage[this.onActive]['image']).width(this.FULL_WIDTH_PERCENT).height(this.FULL_HEIGHT_PERCENT).objectFit(ImageFit.Cover).opacity(this.opacityAngle).transition({ type: TransitionType.Insert, translate: { x: 0, y: 0 } }).transition({ type: TransitionType.Delete, opacity: 0, scale: { x: 0, y: 0 } })}Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Center }){Image($r("app.media.ic_new")).width(11).height(11).margin({left:10,top:3,right:5})Text("換一批").fontSize('8fp').width(40).fontColor('#fff').margin({top:3})}.backgroundColor('#fecc5b').width(50).height(15).borderRadius(10).onClick(()=>{animateTo({ duration: 1000 }, () => {this.flag = !this.flag;this.onActive=(this.onActive+1)%this.arrImage.length;})}).position({ x: 10, y: 10 })Column(){Flex({justifyContent:FlexAlign.SpaceBetween}){ForEach(this.arrImage[this.onActive]['anyArray'],(item)=>{Button(item.name,{ type: ButtonType.Normal,}).fontSize('8fp').borderRadius(10).height(20).width('45%').backgroundColor('#fecc5b').onClick(()=>{console.log('44')if(item.type==1){animateTo({ duration: 1000 }, () => {this.flag = !this.flag;this.onActive=(this.onActive+1)%this.arrImage.length;})}else{}})})}}.margin({top:110,left:10,right:10})Text(this.arrImage[this.onActive]['content']).fontSize('7fp').opacity($r('app.float.detail_immersive_opacity')).margin({ top: '70vp',left:'10vp',right:'10vp' }).textOverflow({ overflow: TextOverflow.Ellipsis }).fontColor('#000').fontWeight('900').maxLines(this.MAX_LINES)}.width(this.FULL_WIDTH_PERCENT).height(this.FULL_HEIGHT_PERCENT).onClick(() => {postCardAction(this, {"action": this.ACTION_TYPE,"abilityName": this.ABILITY_NAME,"params": {"message": this.MESSAGE}});})}
}
元服務項目源碼:https://download.csdn.net/download/aa2528877987/88484307
🚀總結
手語猜一猜元服務的實現借助了HarmonyOS的跨應用數據共享和功能交互特性,讓用戶可以通過手勢輸入手語,并進行識別和猜詞游戲。這種應用方式不僅提供了娛樂和互動的體驗,還促進了手語的學習和交流。通過使用該應用,我深刻體會到了HarmonyOS元服務的便利和靈活性。
開發使用HarmonyOS元服務可以帶來許多好處,包括跨設備互聯、數據共享和交互、靈活性和擴展性,以及性能優化。我鼓勵大家積極嘗試使用HarmonyOS元服務,開發出更好屬于自己的應用。
🚀附錄
- 元服務介紹:元服務-元服務萬能卡片-元服務開發解決方案-華為開發者聯盟
- ArkTS語言介紹: ArkTS 語言 - HarmonyOS應用開發官網
- 端云一體化開發介紹:文檔中心
- 低代碼開發介紹:文檔中心