过前面的学习:快速入门一个 Hello World 程序和编写一个简单的交互程序,我们已经基本了解鸿蒙应用开发的基本流程,这一篇,我们来细化学习下鸿蒙的 UI 框架(基于 Java)。

01
Ability
在开始之前,我们先来了解一个基础概念:Ability。
Ability 从英文的字面上理解是“能力”的意思,同样在鸿蒙的架构体系里,官方的释意:Ability 表示应用程序所具备能力的抽象,是应用程序的重要组成部分。
一个应用可以具备多种能力(即可以包含多个 Ability),HarmonyOS 支持应用以 Ability 为单位进行部 署。
Ability 可以分为 FA(Feature Ability)和 PA(Particle Ability)两种类型,每种类型为开发者提供了不同的模板,以便实现不同的业务功能。
Ability 支持三种模版:
PageAbility:页面模版,用于提供与用户交互的能力。这个也是 FA 唯一支持的模版。
ServiceAbility:服务模版,用于提供后台运行任务的能力。
DataAbility:数据模版,用于对外部提供统一的数据访问抽象。
简单说,你要做 UI 交互,那么就用 FA。需要做非界面的服务/数据处理就用 PA。
层次结构可以参考下图:

上面截图这个指定了一个 page,表示了这是一个 page 模版实例。
同样的,如果你创建的是一个 PA,还可以指定 service 或者 data。
不管是 service 还是 data,都是一个 ability,区别在于开发者怎么定义这个类的职责(是提供服务/数据支持呢,还是作为界面交互?),简单说,取决于你想让你创建的这个 ability 为你提供什么能力。
02
页面跳转
我们在来细说下 PageAbility,上面介绍了 Page 模版是 FA 唯一支持的模版,并且提供了与用户交互的能力(UI),一个 Page 可以由一个或者多个 AbilitySlice 构成。
我们在之前跑 hello world 的时候,有介绍 Ability 是一个路由入口,而 AbilitySlice 则是写交互逻辑的地方。
简单说,当我们创建一个 FA 的时候,比如这个 TestAbility,会同时自动对应创建一个 TestAbilitySlice,TestAbility 相当于是对外可以调用的类,具体的逻辑实现则是在 TestAbilitySlice 中。
而当调用 TestAbility 时,它就通过路由自动映射给 TestAbilitySlice 来提供具体的交互逻辑。
默认情况下,一个 FeatureAbility 会指定一个默认的路由,即通过 setMainRoute 方法来指定其对应的 AbilitySlice,当然我们也可以通过 addActionRoute 方法来修改默认的指定。
具体方法示例如下:
①在 config.json 文件中去添加 actions:
addActionRoute("action.test", TestAbilitySlice.class.getName());
③调用:private void TestAction(){
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder().withAction("action.test")
.build();
intent.setOperation(operation);
startAbility(intent);
}
这里再详细解释下这个 Intent : Intent 是对象之间传递信息的载体。
例如,当一个 Ability 需要启动另一个 Ability 时, 或者一个 AbilitySlice 需要导航到另一个 AbilitySlice 时,可以通过 Intent 指定启动的目 标同时携带相关数据,之前的文章有说过,它就是一个中间件。
这样就能实现 Page 间访问到此 AbilitySlice 了。页面跳转分两种情况:Page内(Ability)跳转和 Page 之间跳转。
当然不管哪种情况,都需要借助中间件 Intent 来实现跳转,同时 Intent 也支持携带参数来传递 Page 间或者 Ability 间的数据参数。
Page 内跳转:同一个 Page 内进行跳转时,即发起跳转的 AbilitySlice 和跳转目标的 AbilitySlice 处于同一个 Page 时,可以使用 present() 方法进行跳转。
如果跳转需要返回结果,可以使用 presentForResult() 方法来实现跳转。用户从跳转目标返回时,系统将会回调 onResult() 来接收和处理返回的结果。
此时需要重写该方法。返回结果是由跳转目标 AbilitySlice 在其生命周期内通过 setResult 方法进行设置。
Page 间跳转:不同 Page 中的 AbilitySlice 是相互不可见的,所以无法通过 present 或者 presentForResult 方法直接跳转到其他 Page 的 AbilitySlice 中。
但是可以通过配置 Intent 的 Action 方式导航到目标的 AbilitySlice。Page 间的导航则可使用 startAbility 或者 startAbilityForResult 方法来切换。
类似的 startAbilityForResult 方法有 onAbilityResult 方法来获取返回结果的回调。
在 Ability 中通过使用 setResult 方法来设置返回结果,参见上面添加 action 的部分。
03
UI 框架
回到 UI 框架(Java),我们可以有两种方式进行 UI 结构的创建:Java 代码和 XML 方式。
①使用代码来构建 UI 界面步骤:
定义布局:DirectionalLayout layout = new DirectionalLayout(this);
定于布局配置:LayoutConfig config = new LayoutConfig(LayoutConfig.MATH_PARENT,LayoutConfig.MATH_PARENT);
设置布局的配置:layout.setLayoutConfig(config);
配置布局背景:ShapeElement element = new ShapeElement();
element.setRgbColor(new RgbColor(255,255,255));
layout.setBackground(element);
在布局中添加组件(这里以文本为例):
Text text = new Text(this);
text.setLayoutConfig(config);
text.setText(“你好,鸿蒙”);
text.setTextColor(new Color(0xFF000000));
text.setTextSize(50);
text.setTextAligment(TextAligment.CENTER);
layout.addComponent(text);
设置 UI 内容:super.setUIContent(layout);
完成以上这些捕捉,就能通过代码形式来创建界面。
②使用 XML 来构建页面:
构建一个 XML 文件:在 base 目录右键创建布局文件:


<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:orientation="vertical">
<Textohos:height="match_content"ohos:width="match_content"ohos:text="你好,鸿蒙"
/>
DirectionalLayout>
Text 标签下还有其他很多参数,同样的大部分组件都有类似或接近的标签设置参数,大家可以输入 ohos 自动补全去尝试即可,基本都可以通过字面意思直接明白用途,这里就不再赘述了。
使用资源映射 ResourceTable 来设置 UI 内容:super.setUIContent(ResourceTable.Layout_mytest);
OK,本篇的内容比较多,从 Ability 讲到 UI 框架,但是它们关联性很大,所以,我就都放在了一起。本篇完,下篇见。

点“阅读原文”了解更多