2021-09-01 14:28:02
0
1. 概述 在HarmonyOS里,Ability是应用所具备能力的抽象,一个应用可以具备多种能力(即可以包含多个Ability),HarmonyOS支持应用以Ability为单位进行部署。其中Page Ability可以用于提供与用户交互的能力,一个Page可以由一个或多个AbilitySlice构成,AbilitySlice是指应用的单个页面及其控制逻辑的总和。
- 在一个Ability里,我们可以使用present()/presentForResult() 方法从一个AbilitySlice导航到一个新的AbilitySlice,即Page内不同AbilitySlice的跳转,如图1-1;
- 我们也可以在AbilitySlice里面使用startAbility()/startAbilityForResult() 方法来启动一个新的Ability,如图1-2。
图1-1 通过present()/presentForResult() 方法实现AbilitySlice间导航
图1-2 构造Operation对象,通过startAbility()/startAbilityForResult()实现不同Page间导航
在本Codelab中,我们尝试构建2个Ability、3个AbilitySlice来完成两种类型的跳转。
参考上面的图,我们在MainAbilitySlice页面,写两个简单的按钮,一个让它实现Page内跳转,另一个让它实现Page间跳转;在NewAbilitySlice和SecondAbilitySlice页面,通过一个按钮来让它回到第一个页面,实际完成图如下。
图1-3 点击第一个按钮跳转到第二个AbilitySlice,然后跳回
图1-4 点击第二个按钮跳转到第二个Ability,然后跳回
2. 任务一:新建项目
在此任务中,您学会如何新建一个项目,并进行相关的设置。
开发准备- 开始前请参考下载与安装软件、配置开发环境,完成DevEco Studio的安装和开发环境配置。
- 开发环境配置完成后,请参考创建和运行Hello World创建工程,以使用Java语言开发、设备类型为 "Phone"的"Application"为例,模板选择"Empty Feature Ability(Java)"。
- 工程创建完成后,使用Phone模拟器运行该工程。
3. 任务二:编写页面布局
在这个任务中,我们需要完成多个页面的新建和设计。在Java UI框架中,系统提供了两种编写布局的方式:在XML中声明UI布局和在代码中创建布局,我们以XML的方式为例。
在完成任务一后,我们可以看到系统自动创建了MainAbility和MainAbilitySlice。在"Project"窗口,点击"entry > src > main > resources > base > layout",打开"ability_main.xml"文件。
我们编写一个文本和两个按钮,使用DependentLayout布局,通过Text和Button组件来实现, "ability_main.xml"的示例代码如下:
- <?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:id="$+id:main_text"
- ohos:text="嗨,我是 MainAbilitySlice,看标题就知道我在哪个Page啦"
- ohos:width="320fp"
- ohos:height="match_content"
- ohos:text_alignment="center"
- ohos:multiple_lines="true"
- ohos:text_size="20fp"
- ohos:above="$+id:enter_second"
- ohos:bottom_margin="50vp"/>
-
- <Button
- ohos:id="$+id:enter_newAbilitySlice"
- ohos:width="260vp"
- ohos:height="45vp"
- ohos:text="导航到 NewAbilitySlice"
- ohos:multiple_lines="true"
- ohos:text_size="20fp"
- ohos:bottom_margin="20vp"
- ohos:center_in_parent="true"
- ohos:background_element="$graphic:background_ability_main"/>
-
- <Button
- ohos:id="$+id:enter_second"
- ohos:width="260vp"
- ohos:height="45vp"
- ohos:text="导航到 SecondAbility"
- ohos:multiple_lines="true"
- ohos:text_size="20fp"
- ohos:bottom_margin="20vp"
- ohos:center_in_parent="true"
- ohos:background_element="$graphic:background_ability_main"/>
-
- </DirectionalLayout>
复制代码
代码中的按钮使用了background_element="$graphic: background_ability_main " ,即"entry > src > main > resources > base > graphic"中的"background_ability_main.xml"文件,示例代码为:
- <shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
- ohos:shape="rectangle">
- <corners
- ohos:radius="10"/>
- <solid
- ohos:color="#ffc0c0c0"/>
- <stroke
- ohos:color="#ff00ff7f"
- ohos:width="0.4vp"/>
- </shape>
复制代码
完成上述步骤后,页面布局如下图所示:
然后我们来创建第二个Page,在"Project"窗口,打开"entry > src > main > java > 包名",右键点击"slice"文件夹,选择"New > Ability > Empty Page Ability(Java)",命名为"SecondAbility",单击回车键,系统会创建"SecondAbility.java"和"slice/SecondAbilitySlice.java"。
在"Project"窗口,点击"entry > src > main > resources > base > layout",打开"ability_second.xml"文件,增加信息显示区域和跳转按钮,示例代码如下。
- <?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:id="$+id:second_text"
- ohos:width="320fp"
- ohos:height="match_content"
- ohos:multiple_lines="true"
- ohos:text="嗨, 我是 SecondAbilitySlice"
- ohos:text_alignment="center"
- ohos:text_size="20fp"
- ohos:above="$+id:second_back_first"
- ohos:bottom_margin="50vp"/>
-
- <Button
- ohos:id="$+id:second_back_first"
- ohos:width="260vp"
- ohos:height="45vp"
- ohos:text="回到MainAbility"
- ohos:multiple_lines="true"
- ohos:text_size="20fp"
- ohos:bottom_margin="20vp"
- ohos:center_in_parent="true"
- ohos:background_element="$graphic:background_ability_main"/>
-
- </DirectionalLayout>
复制代码
第二个页面布局完成了,如下图所示:
最后我们在"entry > src > main > java> 包名 >slice"文件夹上右键新建一个"NewAbilitySlice.java"文件,并在"entry > src > main > resources > base > layout"里新建"ability_main_new.xml"文件,用于实现Page之内跳转调用。
"ability_main_new.xml"文件中,同样增加一个信息显示区域和跳转按钮,示例代码为:
- <?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:id="$+id:new_text"
- ohos:width="320fp"
- ohos:height="match_content"
- ohos:multiple_lines="true"
- ohos:text="我是 NewAbilitySlice。麻烦看看标题,请告诉我现在在哪个Page呢?"
- ohos:text_alignment="center"
- ohos:text_size="20fp"
- ohos:above="$+id:second_back_first"
- ohos:bottom_margin="50vp"/>
-
- <Button
- ohos:id="$+id:new_to_main"
- ohos:width="260vp"
- ohos:height="45vp"
- ohos:text="回到MainAbilitySlice"
- ohos:multiple_lines="true"
- ohos:text_size="20fp"
- ohos:bottom_margin="20vp"
- ohos:center_in_parent="true"
- ohos:background_element="$graphic:background_ability_main"/>
-
- </DirectionalLayout>
复制代码
完成上述代码后,页面布局如下图所示:
最后我们对Ability页面的标题栏进行修改,便于我们分辨页面。
在"Project"窗口,点击"entry > src > main ",打开"config.json"文件,修改"abilities"中两个"label"字段分别为"Page MainAbility""Page SecondAbility"。
默认情况下,label字段生成为引用模式不可直接修改,按住Ctrl鼠标左键点击该字段,就可以跳转到被引用的string.json文件,修改对应字段就可以了。
- {
- "string": [
- {
- "name": "entry_MainAbility",
- "value": "Page MainAbility"
- },
- {
- "name": "entry_SecondAbility",
- "value": "Page SecondAbility"
- },
-
- ...
-
- ]
- }
复制代码
4. 任务三:编写AbilitySlice间的导航
打开"entry > src > main > java> 包名 >slice"中的"MainAbilitySlice.java"文件,添加两个按钮的响应逻辑,实现点击按钮跳转到下一页。
其中,Page内AbilitySlice间的导航选择使用presentForResult()实现,可以获得从导航目标AbilitySlice返回时的返回结果;Page间的导航,我们在后文完成startEnterSecondAbility()方法后实现。
- private Text backValueText;
-
- [url=home.php?mod=space&uid=2735960]@Override[/url]
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_ability_main);
-
- //start entering the NewAbilitySlice
- Component enterNewAbilitySliceButton = findComponentById(ResourceTable.Id_enter_newAbilitySlice);
- enterNewAbilitySliceButton.setClickedListener(listener -> presentForResult(new NewAbilitySlice() , new Intent(), 0));
-
- //start entering the SecondAbility page
- Component enterSecondAbilityButton = findComponentById(ResourceTable.Id_enter_second);
- enterSecondAbilityButton.setClickedListener(component -> startEnterSecondAbility());
-
- backValueText = (Text) findComponentById(ResourceTable.Id_main_text);
- }
复制代码
打开同文件夹下新建的"NewAbilitySlice.Java"文件,通过setResult()完成返回结果的实现。具体参考代码如下:
- package com.huawei.abilityintent.slice;
-
- import com.huawei.abilityintent.ResourceTable;
- import ohos.aafwk.ability.AbilitySlice;
- import ohos.aafwk.content.Intent;
- import ohos.agp.components.Component;
-
- public class NewAbilitySlice extends AbilitySlice {
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_ability_main_new);
-
- Component newToMainButton = findComponentById(ResourceTable.Id_new_to_main);
- newToMainButton.setClickedListener(component -> terminate());
- }
-
- @Override
- public void onActive() {
- super.onActive();
-
- Intent intent = new Intent();
- intent.setParam("key", "我从NewAbilitySlice跳回来咯");
- setResult(intent);
- }
-
- @Override
- public void onForeground(Intent intent) {
- super.onForeground(intent);
- }
- }
复制代码
然后我们继续在"MainAbilitySlice.java"中补充下面代码,通过onResult完成返回结果的接收,并显示在页面的Text控件中。
- /**
- * Result of presentForResult()
- */
- @Override
- protected void onResult(int requestCode, Intent resultIntent) {
- if (requestCode != 0 || resultIntent == null) {
- return;
- }
- String result = resultIntent.getStringParam("key");
- backValueText.setText(result);
- }
复制代码
这样,Page内的两个AbilitySlice的导航跳转就完成了。
5. 任务四:编写Page之间的导航 在"entry > src > main > java> 包名 "中"MainAbility.java"文件中,我们可以看到在onStart()中已经通过路由导航到MainAbilitySlice页面。
- public class MainAbility extends Ability {
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setMainRoute(MainAbilitySlice.class.getName());
- }
- }
复制代码
同理"SecondAbility.java"也已经导航到"SecondAbilitySlice.java"页面,接下来我们来完成两个Page Ability之间的导航。
打开 "entry > src > main > java> 包名 >slice"中的"MainAbilitySlice.java"文件,我们进一步完成Page间导航按钮的响应逻辑,实现对应的方法startEnterSecondAbility()。
Page间的导航可以使用startAbility()或startAbilityForResult()方法,获得返回结果的回调为onAbilityResult()。为了获取返回值,我们这里使用startAbilityForResult()方法跳转到SecondAbility。
示例代码如下:
- /**
- * Explicit Startup
- */
- private void startEnterSecondAbility() {
- Intent intent = new Intent();
- Operation operation = new Intent.OperationBuilder().withDeviceId("")
- .withBundleName(getBundleName())
- .withAbilityName("com.huawei.abilityintent.SecondAbility")
- .build();
- intent.setOperation(operation);
- intent.setParam("key", "我从MainAbility进到了SecondAbility");
- startAbilityForResult(intent, 1);
- }
复制代码
在同目录下的"SecondAbilitySlice.java"文件中,我们对从MainAbility中获取到的信息通过Text控件进行展示,并且通过按钮点击事件完成terminnate()操作。
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_ability_second);
-
- Component secondBackFirstButton = findComponentById(ResourceTable.Id_second_back_first);
- secondBackFirstButton.setClickedListener(component -> terminate());
-
- Text showParametersText = (Text) findComponentById(ResourceTable.Id_second_text);
- showParametersText.setText(intent.getStringParam("key"));
- }
复制代码
同时,我们在SecondAbility页面中设置返回MainAbility需要的数据。在"SecondAbility.java"中,我们调用setResult()设置返回结果:
- @Override
- protected void onActive() {
- super.onActive();
- Intent intent = new Intent();
- intent.setParam("key", "我从SecondAbility跳回来啦");
- setResult(0, intent);
- }
复制代码
说明
如果是在AbilitySlice中,我们也可以通过下面方式完成setResult()设置返回结果哟~
getAbility().setResult(0, intent);
最后,在"MainAbilitySlice.java"中增加下面代码,完成返回结果的回调函数onAbilityResult(),将返回结果显示在页面上:
- @Override
- protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
- if (resultCode != 0 || resultData == null) {
- return;
- }
- String result = resultData.getStringParam("key");
- backValueText.setText(result);
- }
复制代码
6. 相关概念与参考
开发指南API 参考
7. 总结
Page内可以使用present()或presentForResult()实现导航,使用presentForResult()时可以获得从导航目标AbilitySlice返回时的返回结果。
- 返回结果由导航目标AbilitySlice在其生命周期内通过setResult()进行设置。
- 当用户从导航目标AbilitySlice返回时,系统将回调onResult()来接收和处理返回结果,您需要重写该方法。
Page间的导航可以使用startAbility()或startAbilityForResult()方法,使用startAbilityForResult()方法时可以获得导航目标Ability返回时的返回结果。
- 在导航目标Ability中调用setResult()来设置返回结果。
- 获得返回结果的回调为onAbilityResult()。
8. 编码挑战
本节提供了一个简单的家庭作业,用来测试您的学习情况。
目标
构建两个Page,各使用一个TextField框实现在两个页面间传递对话,如:
-"早上好,今天天气真不错。"
-"嗯呢!早上好,我正准备去华为体验店体验一下HarmonyOS,要一起去吗~"
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。
侵权投诉