學(xué)習(xí)筆記 | HarmonyOS的頁(yè)面間跳轉(zhuǎn)
想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
前言
大家好,我又回來(lái)啦。這一星期的學(xué)習(xí)時(shí)間又到了。那我們?cè)谇皫讉€(gè)星期講的都是harmonyOS里的分布式能力,可能學(xué)起來(lái)會(huì)相對(duì)較難一點(diǎn),那我們這一星期就找了個(gè)簡(jiǎn)單一點(diǎn)的來(lái)學(xué),那這就是頁(yè)面間的跳轉(zhuǎn)了。雖然這和分布式能力毫無(wú)相關(guān)也比較簡(jiǎn)單,但也不是說(shuō)明這就不重要了,在所有的應(yīng)用中都基本涉及到了這一個(gè)能力,把這學(xué)好了,也可以為我們后面的應(yīng)用開(kāi)發(fā)打下一個(gè)非常良好的基礎(chǔ)。
那現(xiàn)在就先開(kāi)始我們這星期的西之旅吧!
正文
說(shuō)到頁(yè)面跳轉(zhuǎn)就不得不提到Ability,Ability是應(yīng)用所具備能力的抽象,一個(gè)應(yīng)用可以具備多種能力(即可以包含多個(gè)Ability)。Page Ability可以用于提供與用戶交互的能力,一個(gè)Page可以由一個(gè)或多個(gè)AbilitySlice構(gòu)成的,那AbilitySlice又是什么呢,AbilitySlice可以用于實(shí)現(xiàn)一個(gè)頁(yè)面的邏輯。
創(chuàng)建工程
還是和往常一樣,創(chuàng)建一個(gè)名為MyJump的手機(jī)應(yīng)用。

一個(gè)page包含多個(gè)AbilitySlice
設(shè)置UI界面
在graphic目錄下增加一個(gè)background_button的文件,這個(gè)文件可以用于我們按鈕的背景的設(shè)置。

- <?xml version="1.0" encoding="UTF-8" ?>
 - <shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
 - ohos:shape="rectangle">
 - <solid
 - ohos:color="#007DFF"/>
 - <corners
 - ohos:radius="100"/>
 - </shape>
 
接下來(lái)到layout目錄下增加一個(gè)名為ability_second的文件。

- <?xml version="1.0" encoding="utf-8"?>
 - <DirectionalLayout
 - xmlns:ohos="http://schemas.huawei.com/res/ohos"
 - ohos:height="match_parent"
 - ohos:width="match_parent"
 - ohos:alignment="center"
 - ohos:orientation="vertical">
 - <Text
 - ohos:height="match_content"
 - ohos:width="match_content"
 - ohos:id="$+id:text_second"
 - ohos:background_element="$graphic:background_ability_main"
 - ohos:layout_alignment="horizontal_center"
 - ohos:text="This is SecondAbility"
 - ohos:text_size="30vp"/>
 - <Button
 - ohos:height="match_content"
 - ohos:width="match_parent"
 - ohos:id="$+id:button_second"
 - ohos:background_element="$graphic:background_button"
 - ohos:text="返回"
 - ohos:text_color="#FFFFFF"
 - ohos:text_size="19vp"
 - ohos:top_padding="8vp"
 - ohos:bottom_padding="8vp"
 - ohos:top_margin="20vp"/>
 - </DirectionalLayout>
 
跳轉(zhuǎn)動(dòng)作的實(shí)現(xiàn)
接下來(lái)我們就要在Slice目錄下增加一個(gè)類,名為SecondAbilitySlice。


- package com.example.myjump.slice;
 - import com.example.myjump.ResourceTable;
 - import ohos.aafwk.ability.Ability;
 - import ohos.aafwk.content.Intent;
 - public class SecondAbilitySlice extends AbilitySlice {
 - @Override
 - protected void onStart(Intent intent) {
 - super.onStart(intent);
 - super.setUIContent(ResourceTable.Layout_ability_second);
 - }
 - @Override
 - protected void onActive() {
 - super.onActive();
 - }
 - @Override
 - protected void onForeground(Intent intent) {
 - super.onForeground(intent);
 - }
 - }
 
接下來(lái)是MainAbilitySlice里編寫代碼,使得點(diǎn)擊按鈕能跳轉(zhuǎn)到SecondAbilitySlice。
- Button buttonsecond = (Button)findComponentById(ResourceTable.Id_page1);
 - buttonsecond.setClickedListener(new Component.ClickedListener() {
 - @Override
 - public void onClick(Component component) {
 - Intent intent1 = new Intent();
 - present(new SecondAbilitySlice(),intent1); //跳轉(zhuǎn)到其他頁(yè)面
 - }
 - });
 
那跳轉(zhuǎn)到了SecondAbilitySlice,總要有一個(gè)按鈕可以跳轉(zhuǎn)回原來(lái)的頁(yè)面吧,那我們接下來(lái)就編寫代碼,使得點(diǎn)擊按鈕可以銷毀當(dāng)前頁(yè)面,返回MainAbilitySlice。
- Button button = (Button)findComponentById(ResourceTable.Id_button_second);
 - button.setClickedListener(new Component.ClickedListener() {
 - @Override
 - public void onClick(Component component) {
 - terminate(); //銷毀當(dāng)前頁(yè)面
 - }
 - });
 


那有的人就說(shuō)了,這個(gè)頁(yè)面的數(shù)據(jù)也想帶到那個(gè)頁(yè)面應(yīng)該怎么辦呢。沒(méi)事不慌,問(wèn)題不大。接下來(lái)我們就來(lái)解決攜帶數(shù)據(jù)的問(wèn)題。
我們可以在跳轉(zhuǎn)動(dòng)作執(zhí)行之前,將數(shù)據(jù)以鍵值對(duì)的形式儲(chǔ)存到網(wǎng)絡(luò)中(intent),讓其帶到另外一個(gè)頁(yè)面。
- intent1.setParam("key","the ability is same!"); //將數(shù)據(jù)儲(chǔ)存到intent中,讓其以形參的形式傳到另外一個(gè)頁(yè)面
 
然后在SecondAbilitySlice中先定義一個(gè)輸出控制臺(tái),用于輸出intent中攜帶的數(shù)據(jù),然后在onStart里輸出對(duì)應(yīng)的數(shù)據(jù)。
- HiLog.info(TAG, intent.getStringParam("key")); //用于輸出intent中攜帶的key對(duì)應(yīng)的數(shù)據(jù)
 
那怎么將銷毀的頁(yè)面的數(shù)據(jù)往回帶呢,是不是還是用相同的方法呢。那方法也挺相識(shí)的,也是將數(shù)據(jù)寫到intent中,然后調(diào)用setResult函數(shù),然后將intent傳到該函數(shù)里面。在點(diǎn)擊函數(shù)里的代碼如下:
- Intent intent1 = new Intent();
 - intent1.setParam("second","我是SecondAbility!");
 - setResult(intent1);
 - terminate(); //銷毀當(dāng)前頁(yè)面
 
那這個(gè)setResult()函數(shù)有什么用呢,這個(gè)函數(shù)調(diào)用之后呢,在MainAbilitySlice里就會(huì)調(diào)用onResult()函數(shù),同時(shí)我們應(yīng)該將頁(yè)面跳轉(zhuǎn)所用到的present()函數(shù)改為presentForResult()函數(shù),在這個(gè)函數(shù)里面多了一個(gè)請(qǐng)求碼的參數(shù),請(qǐng)求碼是用于標(biāo)識(shí)某一個(gè)請(qǐng)求的,也就是用來(lái)區(qū)分是哪個(gè)頁(yè)面銷毀頁(yè)面之后返回的,請(qǐng)求碼是一個(gè)非負(fù)的整數(shù),我們就定義請(qǐng)求碼為0,然后調(diào)用presentForResult函數(shù)。
- presentForResult(new SecondAbilitySlice(),intent1, request_code); //跳轉(zhuǎn)到其他頁(yè)面
 
在onResult()函數(shù)中,會(huì)傳來(lái)兩個(gè)參數(shù),一個(gè)就是網(wǎng)絡(luò)resultIntent,另外一個(gè)就是請(qǐng)求碼requestCode,這個(gè)請(qǐng)求碼就是用來(lái)區(qū)分是哪個(gè)頁(yè)面銷毀之后返回來(lái)的。例如我們剛剛在用presentForResult跳轉(zhuǎn)到SecondAbilitySlice時(shí)用的請(qǐng)求碼就為0,那從SecondAbilitySlice返回的請(qǐng)求碼就是0。那onResult怎么重寫呢,代碼如下:
- @Override
 - protected void onResult(int requestCode, Intent resultIntent) {
 - super.onResult(requestCode, resultIntent);
 - //這個(gè)requestCode可以用來(lái)區(qū)分是哪個(gè)頁(yè)面返回的數(shù)據(jù),我們剛剛傳遞的請(qǐng)求碼為0,那從SecondAbilitySlice返回的請(qǐng)求碼就為0
 - if(resultIntent != null && requestCode == request_code) {
 - HiLog.info(TAG, resultIntent.getStringParam("second"));
 - }
 - }
 
那再次運(yùn)行程序,和剛剛程序的區(qū)別就是在輸出臺(tái)會(huì)輸出下面兩句話:

第一句話是在MainAbilitySlice點(diǎn)擊按鈕跳轉(zhuǎn)到SecondAbilitySlice時(shí),在SecondAbilitySlice輸出的,另外一句是在SecondAbilitySlice點(diǎn)擊返回,在MainAbilitySlice輸出的。
一個(gè)page包含一個(gè)AbilitySlice
在com.example.myjump目錄下新建一個(gè)page ability,命名為ThirdAbility。

在ability_third設(shè)置界面
- <?xml version="1.0" encoding="utf-8"?>
 - <DirectionalLayout
 - xmlns:ohos="http://schemas.huawei.com/res/ohos"
 - ohos:height="match_parent"
 - ohos:width="match_parent"
 - ohos:alignment="center"
 - ohos:orientation="vertical">
 - <Text
 - ohos:height="match_content"
 - ohos:width="match_content"
 - ohos:id="$+id:text_third"
 - ohos:background_element="$graphic:background_ability_third"
 - ohos:layout_alignment="horizontal_center"
 - ohos:text="This is ThirdAbility"
 - ohos:text_size="30vp"/>
 - <Button
 - ohos:height="match_content"
 - ohos:width="match_parent"
 - ohos:id="$+id:button_third"
 - ohos:background_element="$graphic:background_button"
 - ohos:text="返回"
 - ohos:text_color="#FFFFFF"
 - ohos:text_size="19vp"
 - ohos:top_padding="8vp"
 - ohos:bottom_padding="8vp"
 - ohos:top_margin="20vp"/>
 - </DirectionalLayout>
 
編寫跳轉(zhuǎn)動(dòng)作
在MainAbilitySlice編寫代碼,完成點(diǎn)擊按鈕跳轉(zhuǎn)到ThirdAbilitySlice去。
先構(gòu)建一個(gè)Intent.OperationBuilder實(shí)例,然后鏈?zhǔn)秸{(diào)用withDeviceId、withBundleName、withAbilityName、build。
- Button buttonthird = (Button)findComponentById(ResourceTable.Id_page2);
 - buttonthird.setClickedListener(new Component.ClickedListener() {
 - @Override
 - public void onClick(Component component) {
 - Intent intent1 = new Intent();
 - Operation operation = new Intent.OperationBuilder() //構(gòu)建一個(gè)Intent.OperationBuilder實(shí)例
 - .withDeviceId("")
 - .withBundleName(getBundleName())
 - .withAbilityName(ThirdAbility.class.getName())
 - .build();
 - intent1.setOperation(operation);
 - startAbility(intent1);
 - }
 - });
 
那同樣的,我們還需要在ThirdAbilitySlice中編寫代碼,完成點(diǎn)擊返回按鈕銷毀當(dāng)前頁(yè)面,銷毀ThirdAbilitySlice,回到MainAbilitySlice。那有人就覺(jué)得用剛才那個(gè)terminate函數(shù)不就行了嗎,那這就大錯(cuò)特錯(cuò)了,在一個(gè)Ability下的不同AbilitySlice就是這樣子銷毀頁(yè)面的,但在不同的Ability下的話,需要調(diào)用terminateAbility函數(shù),那我們就在點(diǎn)擊事件中去調(diào)用這個(gè)函數(shù)。
- Button button = (Button)findComponentById(ResourceTable.Id_button_third);
 - button.setClickedListener(new Component.ClickedListener() {
 - @Override
 - public void onClick(Component component) {
 - terminateAbility();
 - }
 - });
 
運(yùn)行一下查看結(jié)果。


解決攜帶數(shù)據(jù)的問(wèn)題
首先怎么把MainAbilitySlice的數(shù)據(jù)帶到ThirdAbilitySlice呢,還是和剛剛是相同的,把數(shù)據(jù)以鍵值對(duì)的形式寫到intent中,而且還是用相同的方法setParam。
- intent1.setParam("key","the ability is different!");
 
接下來(lái)還是相同的,在ThirdAbilitySlice里面定義一個(gè)輸出控制臺(tái),然后把intent攜帶的數(shù)據(jù)在onStart輸出出來(lái)。
相似的,我們接下來(lái)還是實(shí)現(xiàn)怎么銷毀頁(yè)面之后把數(shù)據(jù)也帶到MainAbility。那我們還是仍然把數(shù)據(jù)寫到intent中,然后調(diào)用getAbility().setResult(),這個(gè)函數(shù)里面有兩個(gè)參數(shù),第二個(gè)就是那個(gè)intent,第一個(gè)是一個(gè)響應(yīng)碼,這個(gè)響應(yīng)碼是用于標(biāo)識(shí)某一次響應(yīng)的,作用也和剛剛的標(biāo)識(shí)碼是相識(shí)的。這里我們就定義一個(gè)響應(yīng)碼為1,然后調(diào)用該函數(shù)。最后調(diào)用terminAbility函數(shù)來(lái)實(shí)現(xiàn)頁(yè)面的銷毀。
- HiLog.info(TAG, intent.getStringParam("key")); //用于輸出intent中攜帶的key對(duì)應(yīng)的數(shù)據(jù)
 - Button button = (Button)findComponentById(ResourceTable.Id_button_third);
 - button.setClickedListener(new Component.ClickedListener() {
 - @Override
 - public void onClick(Component component) {
 - Intent intent1 = new Intent();
 - intent1.setParam("third","我是從ThirdAbility來(lái)的!");
 - getAbility().setResult(resultCode, intent1);
 - terminateAbility();
 - }
 - });
 
這樣子我們就完成了頁(yè)面的銷毀工作了,下面我們需要在MainAbilitySlice來(lái)接受頁(yè)面銷毀后帶來(lái)的數(shù)據(jù)。同樣的還是把startAbility()改為startAbilityForResult(),然后在參數(shù)里面多加一個(gè)響應(yīng)碼。然后再重寫onAbilityResult函數(shù),當(dāng)頁(yè)面銷毀之后,會(huì)自動(dòng)調(diào)用該函數(shù),那我們就可以在這個(gè)函數(shù)里面接收數(shù)據(jù)了。在該函數(shù)中會(huì)有三個(gè)參數(shù),第一個(gè)參數(shù)是請(qǐng)求碼,也就是我們最開(kāi)始在MainAbilitySlice里跳轉(zhuǎn)到ThirdAbilitySlice時(shí)的參數(shù),第二個(gè)是一個(gè)響應(yīng)碼,也是我們剛剛在getAbility().setResult()中設(shè)置的參數(shù),最后一個(gè)就是那個(gè)intent了,數(shù)據(jù)也是在這個(gè)里面的。
- @Override
 - protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
 - super.onAbilityResult(requestCode, resultCode, resultData);
 - if (requestCode == request_code && resultCode == result_code && resultData != null) {
 - HiLog.info(TAG, resultData.getStringParam("third"));
 - }
 - }
 
那就讓我們來(lái)看看運(yùn)行的效果吧!

第一句話是點(diǎn)擊“jump to ThirdAbility”按鈕時(shí)跳轉(zhuǎn)到ThirdAbilitySlice頁(yè)面輸出的,另外一句是點(diǎn)擊返回按鈕銷毀頁(yè)面回到MainAbilitySlice輸出的。
結(jié)語(yǔ)
源碼我會(huì)放到附件中的,有需求的可以自行下載自行學(xué)習(xí),大家有什么看不懂的地方可以私信問(wèn)我或者對(duì)照源碼進(jìn)行學(xué)習(xí)。
https://harmonyos.51cto.com/resource/1251
想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
















 
 
 
 
 
 
 