鴻蒙應(yīng)用開發(fā)案例實戰(zhàn)(ArkTS版)(AI助學(xué))(微課版) 課件 項目7 融會貫通-七彩天氣App開發(fā)之旅_第1頁
鴻蒙應(yīng)用開發(fā)案例實戰(zhàn)(ArkTS版)(AI助學(xué))(微課版) 課件 項目7 融會貫通-七彩天氣App開發(fā)之旅_第2頁
鴻蒙應(yīng)用開發(fā)案例實戰(zhàn)(ArkTS版)(AI助學(xué))(微課版) 課件 項目7 融會貫通-七彩天氣App開發(fā)之旅_第3頁
鴻蒙應(yīng)用開發(fā)案例實戰(zhàn)(ArkTS版)(AI助學(xué))(微課版) 課件 項目7 融會貫通-七彩天氣App開發(fā)之旅_第4頁
鴻蒙應(yīng)用開發(fā)案例實戰(zhàn)(ArkTS版)(AI助學(xué))(微課版) 課件 項目7 融會貫通-七彩天氣App開發(fā)之旅_第5頁
已閱讀5頁,還剩139頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

HarmonyOS鴻蒙應(yīng)用開發(fā)授課:課程團(tuán)隊項目七目錄03應(yīng)用主頁02應(yīng)用開屏頁01搭建開發(fā)工程04“我的”頁面05登錄頁面06個人信息頁面07天氣詳情頁面08新聞模塊搭建開發(fā)工程01工程中模塊的設(shè)計

一個應(yīng)用通常會包含多種功能,將不同的功能按模塊來劃分和管理是一種良好的設(shè)計方式。在開發(fā)過程中,可以將每個功能作為一個獨立的模塊進(jìn)行開發(fā),模塊可以包含源代碼、資源文件、第三方庫、配置文件等,每一個模塊可以獨立編譯來實現(xiàn)特定的功能。這種模塊化、松耦合的應(yīng)用管理方式有助于應(yīng)用的開發(fā)、維護(hù)與擴(kuò)展。模塊的類型

模塊按照使用場景可以分為兩種類型:Ability類型的模塊和Library類型的模塊1、Ablibity類型的模塊每一個Ability類型的模塊編譯后,都會生成一個以hap為擴(kuò)展名的文件,它被稱為HAP(HarmonyAbilityPackage)。HAP可以獨立安裝和運行,是應(yīng)用安裝的基本單位,一個應(yīng)用可以包含一個或多個HAP,HAP具體包含如下兩種類型。?

entry類型:應(yīng)用的主模塊包含應(yīng)用的入口界面、入口圖標(biāo)和主功能特性,編譯后生成entry類型的HAP。每一個應(yīng)用分發(fā)到同一類型的設(shè)備上的應(yīng)用程序包APP(ApplicationPackage),只能包含唯一一個entry類型的HAP。?

feature類型:應(yīng)用的動態(tài)特性模塊編譯后生成feature類型的HAP。一個應(yīng)用可以包含一個或多個feature類型的HAP,也可以不包含feature類型的HAP。模塊的類型

模塊按照使用場景可以分為兩種類型:Ability類型的模塊和Library類型的模塊2、Library類型的模塊Library類型的模塊用于實現(xiàn)代碼和資源的共享。同一個Library類型的模塊可以被其他模塊多次引用,合理地使用該類型的模塊能夠降低開發(fā)和維護(hù)成本。Library類型的模塊分為Static和Shared兩種類型,編譯后會生成共享包。

?StaticLibrary:靜態(tài)共享庫。編譯后會生成一個以“har”為擴(kuò)展名的文件,即靜態(tài)共享包HAR。

?SharedLibrary:動態(tài)共享庫。編譯后會生成一個以“hsp”為擴(kuò)展名的文件,即動態(tài)共享包HSP。HAP與APP的區(qū)別HarmonyOS工程的構(gòu)建產(chǎn)物為APP,APP是用于應(yīng)用或服務(wù)上架的文件。HAP是應(yīng)用或服務(wù)可以獨立運行在設(shè)備中的形態(tài),也是應(yīng)用安裝的基本單位,在DevEcoStudio工程目錄中,一個HAP對應(yīng)一個模塊。應(yīng)用打包時,每個模塊對應(yīng)生成一個.hap文件。應(yīng)用如果包含多個模塊,則在應(yīng)用市場上架時,會將多個.hap文件打包成一個.app文件(稱為Bundle),但在云端分發(fā)和端側(cè)安裝時,仍然以HAP為基本單位。為了能夠正常分發(fā)和安裝應(yīng)用,需要保證一個應(yīng)用安裝到設(shè)備時,模塊的名稱、Ability的名稱不重復(fù),并且只有一個entry類型的模塊與目標(biāo)設(shè)備相對應(yīng)。認(rèn)識配置文件

配置文件是用于向編譯工具、操作系統(tǒng)和應(yīng)用市場提供當(dāng)前應(yīng)用的基本信息的文件。HarmonyOS工程app.json5在AppScope中module.json5在具體模塊中app.json5應(yīng)用級全局配置1.基礎(chǔ)標(biāo)識信息bundleName:應(yīng)用唯一標(biāo)識符(反向域名格式,如com.example.app),用于系統(tǒng)級應(yīng)用識別vendor:開發(fā)者組織/廠商信息,與應(yīng)用商店分發(fā)體系關(guān)聯(lián)versionCode/versionName:構(gòu)成版本管理雙因素,前者用于內(nèi)部版本追蹤,后者面向用戶展示icon:應(yīng)用圖標(biāo)label:應(yīng)用名稱

2.設(shè)備適配策略targetDeviceTypes:聲明支持的設(shè)備類型(phone/tablet/tv/wearable等),決定應(yīng)用在設(shè)備市場的可見性deviceSpecificConfigs:針對不同設(shè)備的差異化配置(如平板端采用分欄布局、穿戴設(shè)備啟用低功耗模式)3.API版本管理minAPIVersion:最低兼容的API版本,控制老舊設(shè)備的安裝限制targetAPIVersion:目標(biāo)開發(fā)版本,決定可使用的API功能集合compatibleAPIVersion:向后兼容版本,確保新功能在老設(shè)備上的降級策略module.json5模塊級功能配置1.模塊元數(shù)據(jù)name:模塊的工程名稱(與代碼目錄關(guān)聯(lián))type:模塊類型(entry/feature/har),分別對應(yīng)主模塊/功能模塊/靜態(tài)庫description:模塊功能說明,用于IDE可視化展示2.組件注冊中心abilities:聲明UIAbility(可視化界面單元)和ExtensionAbility(后臺服務(wù)單元)UIAbility:定義頁面棧管理策略、啟動模式(standard/singleton模式)ExtensionAbility:配置后臺服務(wù)類型(如FormExtension提供卡片能力)forms:服務(wù)卡片配置,包含卡片尺寸、刷新策略、數(shù)據(jù)源綁定3.權(quán)限管理體系requestPermissions:聲明應(yīng)用運行所需的權(quán)限集合實戰(zhàn)操作初步定制應(yīng)用信息應(yīng)用開屏頁02開屏頁(SplashScreen)是用戶啟動應(yīng)用時首先看到的頁面,它對用戶體驗有著重要的影響。它能緩解加載焦慮、強(qiáng)化品牌認(rèn)知,是一個展示品牌形象的首要頁面。應(yīng)用開屏頁的意義創(chuàng)建開屏頁//SplashPage.ets@Entry@ComponentstructSplashPage{

build(){

RelativeContainer(){

Image($r('app.media.bg_splash_img'))

.id('img_splash').objectFit(ImageFit.Fill).width('100%').height('100%')

}

.height('100%').width('100%')

}}創(chuàng)建開屏頁//EntryAbility.ets

onWindowStageCreate(windowStage:window.WindowStage):void{//更改首次加載頁面路徑為開屏頁windowStage.loadContent('pages/SplashPage,(err)=>{});}什么是UIAbilityEntryAbility類是整個entry模塊的入口類,它繼承自UIAbility類。它是系統(tǒng)調(diào)度的基本單元,為應(yīng)用提供繪制界面的窗口。一個應(yīng)用可以包含一個或多個UIAbility組件。將應(yīng)用切換到后臺時,所看到的每一個卡片就對應(yīng)一個UIAbility組件。UIAbility的生命周期UIAbility的生命周期包括Create(創(chuàng)建)、Foreground(前臺)、Background(后臺)、Destroy(銷毀)四個狀態(tài)。UIAbility的生命周期回調(diào)名稱描述onCreate在應(yīng)用加載過程中,UIAbility實例創(chuàng)建完成時,系統(tǒng)會調(diào)用onCreate回調(diào)方法??梢栽谠摶卣{(diào)方法中進(jìn)行頁面初始化操作,如變量定義、資源加載等,用于后續(xù)的UI展示onWindowStageCreateUIAbility實例創(chuàng)建完成之后,在進(jìn)入前臺之前,系統(tǒng)會創(chuàng)建一個WindowStage。WindowStage創(chuàng)建完成后會進(jìn)入onWindowStageCreate回調(diào)方法,可以在該回調(diào)方法中設(shè)置UI加載、WindowStage的事件訂閱onWindowStageDestroy在UIAbility實例銷毀之前,會進(jìn)入onWindowStageDestroy回調(diào)方法,可以在該回調(diào)中釋放UI資源onWindowStageWillDestroy在WindowStage即將銷毀前執(zhí)行,此時WindowStage可以使用onForeground在UIAbility的UI可見之前,如UIAbility切換至前臺時觸發(fā)??梢栽趏nForeground回調(diào)方法中申請系統(tǒng)需要的資源,或者重新申請在onBackground中釋放的資源onBackground在UIAbility的UI完全不可見,如UIAbility切換至后臺時觸發(fā)??梢栽趏nBackground回調(diào)方法中釋放UI不可見時無用的資源,或者在此回調(diào)中執(zhí)行較為耗時的操作,如狀態(tài)保存等onDestroy在UIAbility實例銷毀時觸發(fā)??梢栽趏nDestroy回調(diào)方法中進(jìn)行系統(tǒng)資源的釋放、數(shù)據(jù)的保存等操作沉浸式用戶體驗//

EntryAbility.etsonWindowStageCreate(windowStage:window.WindowStage):void{

//

獲取應(yīng)用主窗口

letwindowClass:window.Window|undefined=undefined;

windowStage.getMainWindow((err:BusinessError,data)=>{

windowClass=data;

//

實現(xiàn)沉浸式效果。方法一:設(shè)置導(dǎo)航欄、狀態(tài)欄不顯示

letnames=[];

windowClass.setWindowSystemBarEnable(names);

//

實現(xiàn)沉浸式效果。方法二:直接全屏顯示,導(dǎo)航欄、狀態(tài)欄也顯示

//windowClass.setWindowLayoutFullScreen(true)

})

//

為沉浸式窗口加載對應(yīng)的目標(biāo)頁面

windowStage.loadContent('pages/SplashPage',(err)

=>{

});}倒計時跳轉(zhuǎn)的實現(xiàn)——確定倒計時按鈕位置//EntryAbility.ets…//定義并導(dǎo)出狀態(tài)欄高度exportletSTATUS_BAR_HEIGHT=0exportdefaultclassEntryAbilityextendsUIAbility{

onWindowStageCreate(windowStage:window.WindowStage):void{

letwindowClass:window.Window|undefined=undefined;

windowStage.getMainWindow((err:BusinessError,data)=>{

windowClass=data;

letnames=[];

windowClass.setWindowSystemBarEnable(names);

//獲取狀態(tài)欄高度,并通過px2vp方法將px數(shù)值轉(zhuǎn)換為vp數(shù)值

STATUS_BAR_HEIGHT=px2vp(windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height)

})

}

…}倒計時跳轉(zhuǎn)的實現(xiàn)——頁面如何跳轉(zhuǎn)頁面路由(@ohos.router)和組件導(dǎo)航(Navigation)Router模塊通過不同的URL,可以方便地進(jìn)行頁面路由,從而輕松地訪問不同的頁面。Router模塊通過頁面棧提供了pushUrl(跳轉(zhuǎn)到指定頁面)、replaceUrl(替換當(dāng)前頁面)、back(返回)等方法用于頁面間的跳轉(zhuǎn)。router.pushUrl:目標(biāo)頁面不會替換當(dāng)前頁面,而是被壓入頁面棧。這樣可以保留當(dāng)前頁面的狀態(tài),并且可以通過返回按鈕或者調(diào)用router.back方法返回當(dāng)前頁面。router.replaceUrl:目標(biāo)頁面會替換當(dāng)前頁面,并銷毀當(dāng)前頁面。這樣可以釋放當(dāng)前頁面的資源,并且無法返回當(dāng)前頁面。倒計時跳轉(zhuǎn)的實現(xiàn)——頁面如何跳轉(zhuǎn)頁面路由(@ohos.router)和組件導(dǎo)航(Navigation)structSplashPage{

@Stateseconds:number=5//倒計時

intervalId?:number

aboutToAppear():void{//倒計時秒數(shù)遞減ervalId=setInterval(()=>{if(--this.seconds<=0){this.toIndex()}},1000);

}

toIndex(){clearInterval(ervalId)//取消定時器//由于開屏頁不需要被返回,直接使用replaceUrl方法即可router.replaceUrl({url:'pages/Index'})

}

build(){RelativeContainer(){Image($r('app.media.bg_splash_img'))Button(`${this.seconds}秒

跳過`).onClick(()=>this.toIndex())}

}}將文字作為資源使用

開屏頁代碼實現(xiàn)中,將倒計時按鈕上的文字“秒

跳過”直接硬編碼在SplashPage.ets文件中。簡單、但是無復(fù)用性{"name":"splash_skip","value":"秒

跳過"}//string.json文件中定義鍵值對//BaseUtils.ets//基礎(chǔ)工具類exportclass

BaseUtils{

staticappCtx=getContext(this).getApplicationContext()

//將資源文件中定義的字符串資源轉(zhuǎn)換成字符串

staticgetStr(resource:Resource):string{

returnBaseUtils.appCtx.resourceManager.getStringSync(resource.id)

}}//SplashPage.ets//使用BaseUtils中的方法Button(`${this.seconds}${BaseUtils.getStr($r('app.string.splash_skip'))}`)自定義組件生命周期

aboutToAppear():void{//倒計時秒數(shù)遞減ervalId=setInterval(()=>{if(--this.seconds<=0){this.toIndex()}},1000);

}aboutToAppear:可理解為即將出現(xiàn)。build方法之前執(zhí)行。onDidBuild:可理解為當(dāng)?shù)拇_構(gòu)建了頁面的組件時。該方法在執(zhí)行自定義組件的build方法之后執(zhí)行。aboutToDisappear:可理解為即將消失。該方法在自定義組件析構(gòu)銷毀之前執(zhí)行。onPageShow:可理解為當(dāng)頁面顯示時。該方法在頁面每次顯示時觸發(fā)一次。onPageHide:可理解為當(dāng)頁面隱藏時。該方法在頁面每次隱藏時觸發(fā)一次。onBackPress:可理解為當(dāng)返回按鈕被點擊時。aboutToReuse:可理解為即將被復(fù)用。aboutToRecycle:可理解為即將被回收利用。onWillApplyTheme:可理解為將要應(yīng)用主題時。應(yīng)用主頁03主頁(Index)是用戶獲取天氣信息的入口。一個直觀、易用的主頁不僅能夠快速傳達(dá)關(guān)鍵的天氣數(shù)據(jù),還能通過高效的導(dǎo)航提升用戶體驗。而底部工具欄作為主頁的重要組成部分,扮演著連接用戶與應(yīng)用功能的橋梁角色。應(yīng)用主頁的意義主頁分析其頁面結(jié)構(gòu)由底部工具欄、上方標(biāo)題欄和中間內(nèi)容區(qū)組成。要實現(xiàn)這樣的頁面結(jié)構(gòu)有很多種方式,但是最佳選擇是:NavigationNavigationNavigation組件是路由導(dǎo)航的根視圖容器,一般作為Page頁面的根容器使用,其內(nèi)部默認(rèn)包含了標(biāo)題欄(含菜單欄)、內(nèi)容區(qū)和工具欄,其中內(nèi)容區(qū)默認(rèn)首頁顯示導(dǎo)航內(nèi)容(Navigation的子組件)或非首頁顯示(NavDestination的子組件),首頁和非首頁通過路由進(jìn)行切換。Navigation的區(qū)域Navigation分為四個區(qū)域:title區(qū)、menu區(qū)、toolbar區(qū)、content區(qū)。@Entry@ComponentstructIndex{

//創(chuàng)建一個NavPathStack對象并將其傳入Navigation,

//使用@Provide裝飾使其可供其他頁面使用

@Provide('pageStack')pageStack:NavPathStack=newNavPathStack()

@BuildermenuBuilder(){

SymbolGlyph($r('sys.symbol.character_book')).fontSize(30)

}

build(){

Navigation(this.pageStack){}

.title('Main').menus(this.menuBuilder())

.toolbarConfiguration([{icon:$r('sys.media.ohos_ic_public_text'),value:'導(dǎo)航'}])

}}NavPathStack頁面跳轉(zhuǎn)NavPathStack通過push相關(guān)接口實現(xiàn)頁面跳轉(zhuǎn)功能。(1)通過頁面名稱跳轉(zhuǎn),并可攜帶參數(shù)。this.pageStack.pushPath({name:"PageOne",param:

"PageOneParam"})this.pageStack.pushPathByName("PageOne","PageOneParam")(2)帶返回回調(diào)的跳轉(zhuǎn),能在頁面出棧時進(jìn)行回調(diào),并獲取和處理返回信息。this.pageStack.pushPathByName('PageOne',"PageOneParam",(popInfo)

=>{

console.log('彈出頁面名稱:'+popI+',返回數(shù)據(jù):'+JSON.stringify(popInfo.result))});(3)帶錯誤碼的跳轉(zhuǎn),跳轉(zhuǎn)結(jié)束會觸發(fā)異步回調(diào),返回錯誤碼和錯誤信息。this.pageStack.pushDestinationByName('PageOne',"PageOneParam")

.catch((error:BusinessError)

=>{

console.error(`跳轉(zhuǎn)失敗,錯誤碼=${error.code},錯誤信息=${error.message}.`);

}).then(()

=>{

console.error('跳轉(zhuǎn)成功.');});NavPathStack頁面返回NavPathStack通過pop相關(guān)接口實現(xiàn)頁面返回功能。//返回上一個頁面this.pageStack.pop(animated?:boolean)this.pageStack.pop(result:Object,animated?:boolean)//返回上一個指定名稱的頁面,中間的頁面都會被彈出this.pageStack.popToName(name:string,animated?:boolean)this.pageStack.popToName(name:string,result:Object,animated?:boolean)//返回指定索引頁面,中間的頁面都會被彈出。頁面棧棧底的頁面索引為0this.pageStack.popToIndex(index:number,animated?:boolean)this.pageStack.popToIndex(index:number,result:Object,animated?:boolean)//返回根主頁(清除頁面棧中所有頁面)this.pageStack.clear(animated?:boolean)NavPathStack頁面替換NavPathStack通過replace相關(guān)接口實現(xiàn)頁面替換功能。this.pageStack.replacePath(info:NavPathInfo,animated?:boolean)this.pageStack.replacePath(info:NavPathInfo,options?:NavigationOptions)this.pageStack.replacePathByName(name:string,param:Object,animated?:boolean)NavPathInfo包含name、param和onPop字段。NavigationOptions中的launchMode參數(shù)可以用于指定替換的模式。NavPathStack頁面刪除NavPathStack通過remove相關(guān)接口實現(xiàn)頁面刪除功能。//刪除頁面棧中指定名稱的所有頁面this.pageStack.removeByName(name:string)//刪除指定索引頁面this.pageStack.removeByIndexes(indexes:Array<number>)NavPathStack參數(shù)獲取NavPathStack通過get相關(guān)接口實現(xiàn)頁面參數(shù)獲取功能。//獲取頁面棧中所有頁面名稱集合this.pageStack.getAllPathName():Array<string>//獲取指定索引頁面?zhèn)鬟f的參數(shù),參數(shù)在push或replace方法中傳遞this.pageStack.getParamByIndex(index:number):unknown|undefined//獲取指定頁面?zhèn)鬟f的參數(shù),參數(shù)在push或replace方法中傳遞this.pageStack.getParamByName(name:string):Array<unknown>//獲取所有指定名稱的頁面的索引集合this.pageStack.getIndexByName(name:string):Array<number>NavPathStack路由攔截NavPathStack提供了setInterception方法,用于設(shè)置Navigation頁面跳轉(zhuǎn)攔截回調(diào)。該方法需要傳入一個NavigationInterception對象,該對象包含三個回調(diào)方法。(1)willShow:頁面跳轉(zhuǎn)前回調(diào),允許操作棧,在當(dāng)前跳轉(zhuǎn)生效。(2)didShow:頁面跳轉(zhuǎn)后回調(diào),在該回調(diào)中操作棧會在下一次跳轉(zhuǎn)生效。(3)modeChange:Navigation顯示模式發(fā)生變更時觸發(fā)該回調(diào)。

用于對未登錄用戶進(jìn)行校驗、強(qiáng)制跳轉(zhuǎn)到登錄頁面的場景利用Navigation搭建七彩天氣主頁基本架構(gòu)//定義頁面棧,使用@Provide裝飾使其可供其他頁面使用@Provide('pageStack')pageStack:NavPathStack=newNavPathStack()build(){Navigation(this.pageStack){//將頁面棧傳入Navigation組件//內(nèi)容區(qū)}.mode(NavigationMode.Stack)//顯示模式:單欄模式.toolbarConfiguration(自定義方法實現(xiàn))//底部工具欄}工具欄按鈕數(shù)據(jù)classNavTabVO{

name:string//按鈕文字

activeIcon:Resource//選中圖標(biāo)

icon:Resource//未選中圖標(biāo)

constructor(name:string,activeIcon:Resource,icon:Resource){=name;this.activeIcon=activeIcon;this.icon=icon;

}}tabVOArray:Array<NavTabVO>=[newNavTabVO('天氣',$r('app.media.ic_index_weather_active'),$r('app.media.ic_index_weather')),newNavTabVO('新聞',$r('app.media.ic_index_news_active'),$r('app.media.ic_index_news')),newNavTabVO('我的',$r('app.media.ic_index_personal_active'),$r('app.media.ic_index_personal')),]利用按鈕數(shù)據(jù)生成工具欄按鈕//當(dāng)前選中的按鈕的索引@StatecurrentIndex:number=0@BuildernavTabBuilder(){

Row(){ForEach(this.tabVOArray,(tabVO:NavTabVO,i)=>{Column(){

//根據(jù)currentIndex決定圖標(biāo)是否高亮Image(this.currentIndex==i?tabVO.activeIcon:tabVO.icon).width(30).objectFit(ImageFit.Contain)Text(tabVO.name).fontSize(12)//根據(jù)currentIndex決定文字是否高亮.fontColor(this.currentIndex==i?$r('app.color.main_color'):$r('app.color.unselected_color'))}.onClick(()=>{this.currentIndex=i//記錄點擊索引})}).layoutWeight(1)

}.width('100%').justifyContent(FlexAlign.SpaceAround)}Navigation的子頁面@Entry@ComponentstructIndex{

@BuilderPageMap(){if(this.currentIndex===0){IndexWeatherPage()//“天氣”頁面}elseif(this.currentIndex===1){IndexNewsPage()//“新聞”頁面}else{IndexPersonalPage()//“我的”頁面}

}

build(){Column(){Navigation(this.pageStack){this.PageMap()}.mode(NavigationMode.Stack)//顯示模式:單欄模式.toolbarConfiguration(this.navTabBuilder)//底部工具欄}

}}三個子頁面@Preview//為了能在IndexWeatherPage.ets頁面單獨查看預(yù)覽效果@ComponentexportstructIndexWeatherPage{

build(){Column(){Text('天氣')}

}}@Preview//為了能在IndexNewsPage.ets頁面單獨查看預(yù)覽效果@ComponentexportstructIndexNewsPage{

build(){Column(){Text('新聞')}

}}@Preview//為了能在IndexPersonalPage.ets頁面單獨查看預(yù)覽效果@ComponentexportstructIndexPersonalPage{

build(){Column(){Text('我的')}

}}“我的”頁面04在移動應(yīng)用中,"我的"頁面是用戶個人中心的核心模塊,通常位于底部導(dǎo)航欄最右側(cè)。這個頁面集中展示用戶個人信息和基礎(chǔ)功能模塊。設(shè)計上采用簡潔清晰的布局方式,頂部顯示用戶頭像和昵稱,下方以條狀式排列各項功能,方便用戶快速查找和設(shè)置。該頁面通過整合分散的個人化功能,有效提升用戶體驗和操作效率?!拔业摹表撁娴囊饬x國際化支持i18n在全球化的今天,應(yīng)用的多語言支持已成為提升用戶體驗和擴(kuò)大受眾范圍的重要因素。在七彩天氣App的“我的”頁面中,點擊“語言”功能條,就可讓應(yīng)用在中英文之間切換。多語言文件創(chuàng)建在reources目錄下新建en_US和zh_CN兩個語言文件夾,并在里面創(chuàng)建string.json資源文件。資源文件配置多語言在base和zh_CN文件夾下的string.json文件中新增下列中文鍵值對。在en_US文件夾下的string.json文件中新增下列英文鍵值對。界面代碼中引用文字資源實現(xiàn)語言切換功能HarmonyOS的LocalizationKit提供了增強(qiáng)的國際化(i18n)能力。i18n是英文單詞internationalization的縮寫,18代替了在i和n之間的18個字母。1.使用時需要通過以下語句進(jìn)行導(dǎo)入import{i18n}from'@kit.LocalizationKit'2.為“語言”功能條添加切換點擊事件this.functionalBar($r("app.media.ic_func_lang"),$r('app.string.personal_lang'),(event)=>{

//中文和英文切換

//獲得應(yīng)用偏好語言if(i18n.System.getAppPreferredLanguage()!='zh-Hans'){

//設(shè)置偏好語言為簡體中文

i18n.System.setAppPreferredLanguage('zh-Hans')}else{

//設(shè)置偏好語言為英文

i18n.System.setAppPreferredLanguage('en-US')}})About彈窗應(yīng)用通過“關(guān)于”(About)彈窗向用戶展示相關(guān)信息。這個小窗口不僅是信息的集合地,還是連接用戶與產(chǎn)品、團(tuán)隊的橋梁。實現(xiàn)彈窗使用時需要通過以下語句進(jìn)行導(dǎo)入import{promptAction}from'@kit.ArkUI';promptAction的方法釋義showToast創(chuàng)建并顯示文本提示框showDialog創(chuàng)建并顯示對話框,對話框響應(yīng)后異步返回結(jié)果showActionMenu創(chuàng)建并顯示操作菜單,操作菜單響應(yīng)后異步返回結(jié)果openCustomDialog打開自定義彈窗closeCustomDialog關(guān)閉自定義彈窗版本號讀取彈窗展示的版本號并非硬編碼在ArkUI中,而是通過讀取應(yīng)用信息來實現(xiàn)的。使用時需要通過以下語句進(jìn)行導(dǎo)入importbundleManagerfrom'@ohos.bundle.bundleManager';bundleManager模塊提供了應(yīng)用信息查詢能力,支持BundleInfo、ApplicationInfo、Ability、ExtensionAbility等信息的查詢。

//異步獲取版本信息

asyncgetAppInfo(){letresult=awaitbundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)this.appVersionName=result.versionName

//也可以直接獲取版本號

//this.appVersionName=BuildProfile.VERSION_NAME

}彈窗核心代碼promptAction.showDialog({

title:$r('app.string.about_title'),

message:util.format(BaseUtils.getStr($r('app.string.about_content')),this.appVersionName),

buttons:[{text:$r('app.string.btn_sure'),color:$r('app.color.main_color'),primary:false}]}){"name""about_content""value""當(dāng)前版本v%s。\n該APP基于HarmonyOSNext版本開發(fā),天氣數(shù)據(jù)來自于高德天氣API。該APP所有源代碼及其它資源僅限學(xué)習(xí)交流使用,不可用作商業(yè)用途。"}登錄攔截為了讓用戶有更好的體驗,應(yīng)用的很多功能都是需要登錄才能使用的,這樣的設(shè)計能為用戶提供個性化的服務(wù)。在七彩天氣App“我的”頁面中,如果用戶沒有登錄,則在點擊頭像或“反饋”時將跳轉(zhuǎn)到登錄頁面。這一功能該如何實現(xiàn)呢?登錄機(jī)制分類機(jī)制一:每次打開應(yīng)用都需要進(jìn)行登錄,這類應(yīng)用對于安全性的要求比較高,如銀行類的應(yīng)用。機(jī)制二:登錄一次之后,會長時間保持登錄狀態(tài),這類應(yīng)用通常注重用戶體驗和便捷性,如購物類應(yīng)用。用戶信息構(gòu)建用戶登錄之后,App從接口獲取用戶信息,并存儲在手機(jī)上用戶點擊“退出登錄”按鈕后,App把存儲于手機(jī)上的用戶信息清空??空值合并操作符Preferences保存、清空用戶信息有了用戶信息類,如何將信息保存在手機(jī)上、又如何將信息從手機(jī)上刪除?在HarmonyOS中,可以使用ArkData的用戶首選項(Preferences)。Preferences保存、清空用戶信息Preferences提供了一系列簡單易用的接口。獲取PreferencesEntryAbility中為整個模塊獲取一個全局的Preferences實例,并將該Preferences實例導(dǎo)出。//EntryAbility.etsimportpreferencesfrom'@ohos.data.preferences';//定義并導(dǎo)出用戶首選項exportletdataPreferences:preferences.Preferences|null=null;exportdefaultclassEntryAbilityextendsUIAbility{onWindowStageCreate(windowStage:window.WindowStage):void{letoptions:preferences.Options={name:'myStore'};//同步方法獲取首選項dataPreferences=preferences.getPreferencesSync(this.context,options)}}使用Preferences的時機(jī)編寫工具類操作用戶信息//用戶信息存儲keyprivatestaticSP_ACCOUNT='SP_ACCOUNT'//獲取用戶信息publicstaticgetAccountSync():AccountVO{letvalue:AccountVO=newAccountVO()try{value=dataPreferences!.getSync(BizUtils.SP_ACCOUNT,newAccountVO())asAccountVO}catch(e){}returnvalue}//判斷是否登錄publicstaticisLogin():boolean{letaccount=BizUtils.getAccountSync()//獲取的account為null或undefined,或id是0,均表示未登錄if(BaseUtils.nullOrUndefined(account)||account!.id==0){returnfalse}returntrue}//保存用戶信息publicstaticsaveAccount(account:AccountVO){//account不為null或undefined時才保存用戶信息if(!BaseUtils.nullOrUndefined(account)){dataPreferences?.putSync(BizUtils.SP_ACCOUNT,account)//同步保存于內(nèi)存中dataPreferences?.flush()//持久化}}

//刪除用戶信息publicstaticremoveAccount(){dataPreferences?.deleteSync(BizUtils.SP_ACCOUNT)dataPreferences?.flush()}}//同時,在BaseUtils中添加下列判斷空變量或未定義變量的方法,供BizUtils調(diào)用。//BaseUtils.etsexportclassBaseUtils{//判斷是否為null或undefinedstaticnullOrUndefined(obj:ESObject){returnnull==obj||undefined==obj;}攔截跳轉(zhuǎn)在有了BizUtils類后,在跳轉(zhuǎn)到需要登錄的頁面中,都可以在點擊事件中使用BizUtils.isLogin()代碼進(jìn)行判斷。然而這樣做對于整個應(yīng)用開發(fā)來說將是一次“災(zāi)難”!我們應(yīng)該想起NavPathStack頁面更改//PersonalInfoPage.ets@Entry@ComponentstructPersonalInfoPage{

//注意點1:定義消費路由,與Index.ets中的@Provide對應(yīng)

@Consume('pageStack')pageStack:NavPathStack

build(){

//注意點2:必須以NavDestination為根容器組件NavDestination(){//此處編寫頁面具體內(nèi)容}.title('個人信息')

}}//注意點3:導(dǎo)出@Builder裝飾器方法,用于生成頁面,配置文件中要用到@BuilderexportfunctiongetPage(){

PersonalInfoPage()}以點擊頭像進(jìn)入的目標(biāo)頁面——個人信息頁面(PersonalInfoPage)為例。頁面更改{"module":{…"routerMap":"$profile:router_map"…}}在module.json5中配置路由文件地址,地址指向profile下的router_map.json文件。在profile中新建配置文件router_map.json,在其中配置頁面的路由信息。{"routerMap":[…{"name":"PersonalInfoPage","pageSourceFile":"src/main/ets/pages/personal/PersonalInfoPage.ets","buildFunction":"getPage","data":{"navNeedLogin":"true","description":"個人信息頁面"}…]}我的頁面跳轉(zhuǎn)//IndexPersonalPage.ets…structIndexPersonalPage{

@Consume('pageStack')pageStack:NavPathStack//消費路由

build(){Scroll(){Column(){Column(){

//頭像Image($r('app.media.avatar_male')).width(70).clipShape(newCircleShape({width:70,height:70})).margin({top:STATUS_BAR_HEIGHT}).onClick(()=>{

//跳轉(zhuǎn)到router_map.json中配置的頁面this.pageStack.pushPath({name:'PersonalInfoPage'})})

}}主頁攔截//Index.etsstructIndex{

//定義頁面棧,使用@Provide裝飾,使其可供其他頁面使用

@Provide('pageStack')pageStack:NavPathStack=newNavPathStack()

aboutToAppear():void{this.pageStack.setInterception({willShow:(from:NavDestinationContext|NavBar,to:NavDestinationContext|NavBar,operation:NavigationOperation,isAnimated:boolean)=>{if(typeofto!=='string'){lettarget:NavDestinationContext=toasNavDestinationContext

//在router_map.json中的data節(jié)點的navNeedLogin,true表示跳轉(zhuǎn)到該頁要驗證登錄

if(target.getConfigInRouteMap()?.data['navNeedLogin']==='true'&&!BizUtils.isLogin()){target.pathStack.pop()//彈出目標(biāo)頁面target.pathStack.pushPathByName('XXXXXXX',null)//跳轉(zhuǎn)到登錄頁面}}}})

}

…}登錄頁面05登錄頁面主要用于身份驗證、新用戶注冊、找回密碼等功能,同時展示品牌信息或服務(wù)條款。其核心作用是確保用戶安全便捷地進(jìn)入系統(tǒng),是連接用戶與服務(wù)的首要交互節(jié)點。登錄頁面router_map.json配置{"name":"LoginPage","pageSourceFile":"src/main/ets/pages/personal/LoginPage.ets","buildFunction":"getPage","data":{"description":"登錄頁面"}}界面UI主要實現(xiàn)structLoginPage{

//消費路由

@Consume('pageStack')pageStack:NavPathStack

build(){//用戶名輸入框TextInput({placeholder:$r('app.string.tip_username')})

.showCounter(true).maxLength(16)

//密碼輸入框TextInput({placeholder:$r('app.string.tip_password')})

.type(InputType.Password)

//登錄按鈕Button($r('app.string.btn_sign_in')).width('100%').backgroundColor($r('app.color.main_color')).shadow({radius:20,offsetX:10,offsetY:10}).onClick(()=>{})//TODO:

登錄方法待實現(xiàn)

}}//導(dǎo)出頁面方法,呼應(yīng)router_map.json中的配置@BuilderexportfunctiongetPage(){

LoginPage()}網(wǎng)絡(luò)服務(wù)HarmonyOS提供了兩種網(wǎng)絡(luò)服務(wù):NetworkKit(網(wǎng)絡(luò)管理服務(wù))RemoteCommunicationKit(遠(yuǎn)場通信服務(wù))1.NetworkKitNetworkKit提供了多種網(wǎng)絡(luò)通信方式,如HTTP、WebSocket、Socket、MDNS等。2.RemoteCommunicationKitRemoteCommunicationKit是華為提供的對HTTP發(fā)起數(shù)據(jù)請求的NAPI封裝。它在底層實現(xiàn)、接口易用性、性能功耗等方面都比NetworkKit出色。如何使用RemoteCommunicationKit?首先需要申請權(quán)限//module.json5文件{"module":{"requestPermissions":[{"name":"ohos.permission.INTERNET"},{"name":"ohos.permission.GET_NETWORK_INFO"}]}}如何使用RemoteCommunicationKit?//步驟1:導(dǎo)入模塊import{rcp}from"@kit.RemoteCommunicationKit";import{BusinessError}from'@kit.BasicServicesKit';//步驟2:創(chuàng)建Request對象constkHttpServerAddress="/fetch";constrequest=newrcp.Request(kHttpServerAddress,"GET");//步驟3:創(chuàng)建會話constsession=rcp.createSession();//步驟4:發(fā)起請求,并處理返回結(jié)果session.fetch(request).then((rep:rcp.Response)=>{

(`Responsesucceeded:${rep}`);}).catch((err:BusinessError)=>{

console.error(`Responseerr:Codeis${err.code},messageis${err.message}`);});rcp模塊提供了對常見HTTP方法的支持,如GET、POST、HEAD、PUT、DELETE、PATCH、OPTIONS等下載并安裝JDK下載安裝JDK8。:8443/artifactory/java-local/jdk/配置環(huán)境變量添加系統(tǒng)環(huán)境變量JAVA_HOME,變量值與安裝目錄一致。添加%JAVA_HOME%\bin到Path。下載安裝MySQL/archives/community/端口配置為3306配置用戶root/123456運行后端服務(wù)打開MySQLWorkbench,導(dǎo)入并運行給定的腳本文件qicai.sql,準(zhǔn)備好數(shù)據(jù)。打開命令行工具,進(jìn)入qicai-1.0.jar所在目錄,執(zhí)行命令“java-jarqicai-1.0.jar”,啟動JAR包。如果啟動之后命令行工具不報錯,則表示服務(wù)啟動成功。登錄接口對接——響應(yīng)數(shù)據(jù)模型封裝Swagger接口文檔地址“http://localhost:9090/swagger-ui.html”,找到登錄接口exportclassBaseResult{code:number=201//響應(yīng)碼:200為正常msg:string=''//響應(yīng)信息data:ESObject={} //業(yè)務(wù)數(shù)據(jù),JSON格式success:boolean=false//自定義字段,可以用于快速判斷結(jié)果constructor(code:number,msg:string,data:string){this.code=code??201this.msg=msg??'訪問異常'this.data=data??{}this.success=this.code==200}}登錄接口對接——業(yè)務(wù)數(shù)據(jù)JSON轉(zhuǎn)換在瀏覽器中輸入“”,就可以進(jìn)入OpenHarmony三方庫中心倉頁面在搜索框中輸入“ef_json”,找到JSON轉(zhuǎn)換工具ef_json。登錄接口對接——業(yè)務(wù)數(shù)據(jù)JSON轉(zhuǎn)換在DevEcoStudio的底部面板中找到Terminal(終端),輸入“ohpminstall@yunkss/ef_json”進(jìn)行安裝登錄接口對接——業(yè)務(wù)數(shù)據(jù)JSON轉(zhuǎn)換為BaseResult添加JSON轉(zhuǎn)換方法//BaseResult.etsimport{JSONArray,JSONObject}from'@yunkss/ef_json'//引入JSON轉(zhuǎn)換所需的類exportclassBaseResult{

//將data數(shù)據(jù)轉(zhuǎn)換成具體類型對象,使用泛型<T>

toObject<T>():T{if(typeofthis.data==='string'){returnJSONObject.parseObject<T>(this.data)}else{returnJSONObject.parseObject<T>(JSONObject.toJSONString(this.data))}

}

//將data數(shù)據(jù)轉(zhuǎn)換成具體類型數(shù)組,使用泛型<T>

toArray<T>():Array<T>{if(typeofthis.data==='string'){returnJSONArray.parseArray<T>(this.data)}else{returnJSONArray.parseArray<T>(JSONArray.toJSONString(this.data))}

}}登錄接口對接——封裝HTTP請求//HttpUtil.etsexportclassHttpUtil{

//定義URL前綴privatestaticURL_PREFIX=''static{

//在靜態(tài)代碼塊中初始化URL前綴,將“主機(jī)ip”替換成自己主機(jī)的IP地址HttpUtil.URL_PREFIX='http://主機(jī)ip:9090'}staticasyncpost(url:string,body:Record<string,string>):Promise<BaseResult>{try{url=HttpUtil.URL_PREFIX+urlletsession=rcp.createSession()letresp=awaitsession.post(url,body)letjsonObj=resp.toJSON()returnnewBaseResult(jsonObj!['code'],jsonObj!['msg'],jsonObj!['data'])}catch(err){console.error(`err:錯誤碼:${err.code},錯誤信息:${err.message}`);}returnnewBaseResult(400,'請稍后再試','{}')}}登錄接口對接——完成登錄頁面功能添加URL//Urls.etsexportclassUrls{staticreadonlyLOGIN="/user/login"http://登錄}登錄接口對接——完成登錄頁面功能修改LoginPage.ets文件//登錄方法privateasynclogin(){

//判斷用戶名和密碼是否已輸入if(BaseUtils.isEmptyStr(this.username)||BaseUtils.isEmptyStr(this.password)){promptAction.showToast({message:'用戶名和密碼都不能為空'})return}this.loading=true//請求開始前l(fā)etresult=awaitHttpUtil.post(Urls.LOGIN,{"username":this.username,"password":MD5.digest(this.password,"hex"),//明文密碼做MD5摘要操作})this.loading=false//請求結(jié)束后if(result.success){letaccount=result.toObject<AccountVO>()//轉(zhuǎn)換為AccountVO實例BizUtils.saveAccount(this.account)//用戶信息持久化this.pageStack.pop()}else{promptAction.showToast({message:('用戶名或密碼錯誤'})}}登錄后個人數(shù)據(jù)如何共享?登錄頁面關(guān)閉之后,在“我的”頁面上自動更新用戶信息?跨頁面狀態(tài)管理什么是狀態(tài)管理?在聲明式UI編程框架中,UI是程序狀態(tài)的運行結(jié)果,應(yīng)用運行時的狀態(tài)是參數(shù)。當(dāng)參數(shù)改變時,UI作為返回結(jié)果,也將進(jìn)行對應(yīng)的改變。這些運行時的狀態(tài)變化所帶來的UI的重新渲染,在ArkUI中統(tǒng)稱為狀態(tài)管理。UI:指將build方法內(nèi)的UI描述和@Builder裝飾的方法內(nèi)的UI描述映射到界面。State:指驅(qū)動UI更新的數(shù)據(jù)。用戶通過觸發(fā)組件的事件方法,改變狀態(tài)數(shù)據(jù)。狀態(tài)數(shù)據(jù)的改變會引起UI的重新渲染。狀態(tài)管理的基本概念//子組件@ComponentstructSelfComponent{

@Statecount:number=0;//狀態(tài)變量

privateincreaseBy:number=1;//常規(guī)變量

build(){

Text(`count:${this.count}increaseBy:${this.increaseBy}`)

}}//父組件@ComponentstructParent{

@Statecount:number=10;

build(){

Column(){

//從父組件初始化,覆蓋本地定義的默認(rèn)值

SelfComponent({count:1,increaseBy:2})

SelfComponent({count:this.count,increaseBy:2})

SelfComponent({increaseBy:3})

}}}@Entry@ComponentstructStateManage{

build(){

Column(){

Pa

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論