鸿蒙开发(第三部分)二
常见布局
概述:
每种布局都根据自身特点提供LayoutConfig供子Component设定布局属性和参数,通过指定布局属性可以对子
Component在布局中的显示效果进行约束。例如:“width”、“height”是最基本的布局属性,它们指定了组件的大
小。
布局分类:
线性布局:DirectionalLayout
权重:也是一种百分比布局。
先计算父布局中,可利用空间之和:父布局可分配区域=父布局宽度-所有固定长度或者宽度大小;
在计算百分比
<?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:orientation="vertical">
<Button
ohos:height="0vp"
ohos:width="100vp"
ohos:text="点我1"
ohos:text_size="35fp"
ohos:text_color="#FFFFFF"
ohos:text_alignment="center"
ohos:background_element="#21A8FD"
ohos:weight="2"/>
<Button
ohos:height="0vp"
ohos:width="100vp"
ohos:text="点我2"
ohos:text_size="35fp"
ohos:text_color="#FFFFFF"
ohos:text_alignment="center"
ohos:background_element="#FF0000"
ohos:weight="1"/>
<Image
ohos:height="match_content"
ohos:width="match_content"
ohos:image_src="$media:girl"/>
</DirectionalLayout>
综合案例:电话拨号界面
<?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:orientation="vertical">
<Text
ohos:height="50vp"
ohos:width="200vp"
ohos:text_size="20fp"
ohos:top_margin="30vp"
ohos:layout_alignment="horizontal_center"
ohos:background_element="$graphic:text_empty"/>
<DirectionalLayout
ohos:height="match_content"
ohos:width="match_parent"
ohos:alignment="horizontal_center"
ohos:orientation="horizontal"
ohos:top_margin="30vp">
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="1"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="2"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="3"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
</DirectionalLayout>
<DirectionalLayout
ohos:height="match_content"
ohos:width="match_parent"
ohos:alignment="horizontal_center"
ohos:orientation="horizontal"
ohos:top_margin="10vp">
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="4"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="5"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="6"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
</DirectionalLayout>
<DirectionalLayout
ohos:height="match_content"
ohos:width="match_parent"
ohos:alignment="horizontal_center"
ohos:orientation="horizontal"
ohos:top_margin="10vp">
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="7"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="8"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="9"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
</DirectionalLayout>
<DirectionalLayout
ohos:height="match_content"
ohos:width="match_parent"
ohos:alignment="horizontal_center"
ohos:orientation="horizontal"
ohos:top_margin="10vp">
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="*"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="0"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
<Button
ohos:height="70vp"
ohos:width="70vp"
ohos:text="#"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:background_element="$graphic:button_state"/>
</DirectionalLayout>
<Button
ohos:height="50vp"
ohos:width="200vp"
ohos:text="CALL"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"
ohos:top_margin="50vp"
ohos:background_element="$graphic:text_empty"
ohos:layout_alignment="horizontal_center"/>
</DirectionalLayout>
相对布局:DependentLayout
核心:
找基准位置
在相对布局中,组件的位置是相对其他组件而言的
代码示例:
<?xml version="1.0" encoding="utf-8"?>
<DependentLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
>
<Text
ohos:id="$+id:text1"
ohos:height="100vp"
ohos:width="100vp"
ohos:text="TEXT1"
ohos:text_size="20fp"
ohos:background_element="#21A8FD"/>
<Text
ohos:id="$+id:text2"
ohos:height="100vp"
ohos:width="100vp"
ohos:text="TEXT2"
ohos:text_size="20fp"
ohos:background_element="#FF0000"
ohos:right_of="$id:text1"
/>
<Text
ohos:height="100vp"
ohos:width="100vp"
ohos:text="TEXT3"
ohos:text_size="20fp"
ohos:background_element="#00FF00"
ohos:below="$id:text2"
ohos:left_margin="100vp"
/>
</DependentLayout>
格子布局:TableLayout
行数和列数两个属性。
如果塞入元素过多,行数自动失效,再加一行。
对齐方式:alignment_type
值:align_contents(页边距对齐)(Margin alignment)
align_edges(边界对齐)(boundary alignment)
页边距对齐,是按照上一个组件的相对边界
边界对齐,是跟上一个组件对齐
其他布局:StackLayout(堆叠布局)、 AdaptiveBoxLayout(自适应盒子布局)
代码示例:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="horizontal"
ohos:row_count="3"
ohos:column_count="3"
ohos:alignment_type="align_edges"
>
<Text
ohos:height="50vp"
ohos:width="50vp"
ohos:background_element="#FF0000"
ohos:text="1"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:left_margin="50vp"
ohos:text_alignment="center"/>
<Text
ohos:height="50vp"
ohos:width="50vp"
ohos:background_element="#00FF00"
ohos:text="2"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"/>
<Text
ohos:height="50vp"
ohos:width="50vp"
ohos:background_element="#0000FF"
ohos:text="3"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"/>
<Text
ohos:height="50vp"
ohos:width="50vp"
ohos:background_element="#FFFF00"
ohos:text="4"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"/>
<Text
ohos:height="50vp"
ohos:width="50vp"
ohos:background_element="#FF00FF"
ohos:text="5"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"/>
<Text
ohos:height="50vp"
ohos:width="50vp"
ohos:background_element="#FF0000"
ohos:text="6"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"/>
<Text
ohos:height="50vp"
ohos:width="50vp"
ohos:background_element="#00FF00"
ohos:text="7"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"/>
<Text
ohos:height="50vp"
ohos:width="50vp"
ohos:background_element="#0000FF"
ohos:text="8"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"/>
<Text
ohos:height="50vp"
ohos:width="50vp"
ohos:background_element="#FFFF00"
ohos:text="9"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"/>
<Text
ohos:height="50vp"
ohos:width="50vp"
ohos:background_element="#0000FF"
ohos:text="10"
ohos:text_size="35fp"
ohos:text_color="#000000"
ohos:text_alignment="center"/>
</TableLayout>
绝对布局:PositionLayout
可以指定组件的具体位置。
自适应布局:AdaptiveBoxLayout
指定一行的范围。
屏幕范围小,每行就展示一个,屏幕范围大,就展示多个
底层还不是太稳定。
组件和布局的包含关系:
布局可以理解为是一个容器,可以容纳组件和其他布局,并规定他们如何进行显示。组件在未被添加到布局中时,
既无法显示也无法交互,因此一个用户界面至少包含一个布局。
Java UI框架提供了一些标准布局功能的容器,它们继承自ComponentContainer,一般以“Layout”结尾,如
DirectionalLayout、DependentLayout等。
组件树:
在一个界面中,最外层是一定是布局,在布局里面可以有组件,也可以有其他布局。所以布局可以理解为是多个组
件形成的那个整体。
ComponentContainer
| | |
Component ComponentContainer Component
| |
Component Component
1.Ability
Ability概述:
Ability是应用所具备能力的抽象,也是应用程序的重要组成部分。一个应用可以具备多种能力(即可以包含多个
Ability),HarmonyOS支持应用以Ability为单位进行部署。
Ability分类:
FA(Feature Ability)
PA(Particle Ability)
每种类型为开发者提供了不同的模板,以便实现不同的业务功能。
Feature Ability(FA)
FA支持Page Ability,简单理解就是手机应用中的一个界面。一个界面就是一个FA。
Page模板是FA唯一支持的模板,用于提供与用户交互的能力。一个Page实例可以包含一组相关页面,每个页面用
一个AbilitySlice实例表示。
Particle Ability(PA)
FA是有有界面的,而Particle Ability(PA)是无界面的,简单理解就是可以运行在后台的一个服务。
P
A支持Service Ability和Data Ability:
1)Service模板
用于提供后台运行任务的能力。
2)Data模板
用于对外部提供统一的数据访问抽象。一般是跟数据相关的,比如:如果我们要运行访问数据库。那么就可以用
PA中的Data模板。
2.Feature Ability(FA)
页面FA和切片之间的关系
页面中如何添加多个切片
页面之间的跳转
想要学习跳转,首先要知道一个知识点就是意图,表示我跳转的时候,跳到哪里以及携带什么参数进行跳转?
3.Intent
概述:
Intent是对象之间传递信息的载体。
例如,当一个Ability需要启动另一个Ability时,或者一个AbilitySlice需要导航到另一个AbilitySlice时,可以通过
Intent指定启动的目标同时携带相关数据。Intent的构成元素包括Operation与Parameters:
Operation
表示要跳转的目的地
Parameters
跳转时所携带的数据
详解:
属性 子属性 描述
Operation Action
表示跳转的时候做什么动作,做什么行为。
通常使用系统预置Action,应用也可以自定义Action。
Entity 表示类别,通常使用系统预置Entity,应用也可以自定义Entity。
Uri 表示Uri描述。
Flags
表示处理Intent的方式。
如Intent.FLAG_ABILITY_CONTINUATION标记在本地Ability是否可以迁移到远端设备继续运行。
BundleName 表示包描述。(跳转到哪个包中)
AbilityName 表示待启动的Ability名称。(跳转到哪个界面中)
DeviceId 表示运行指定Ability的设备ID。(跳转到哪台设备中)
Parameters 无
开发者可以通过Parameters传递某些请求所需的额外信息。
一般是通过键值对的形式保存参数。
练习:
在第一个界面中给Intent添加用户名:zhangsan和用户等级:V8。
在第二个界面中通过Intent中的键,获取到对应的值。
代码示例:
//第一个界面中的代码
public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
Button button;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
button = (Button) findComponentById(ResourceTable.Id_text_button);
button.setClickedListener(this);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
@Override
public void onClick(Component component) {
if(component == button){
//跳转页面
//明确要跳转的页面
Intent i = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")//本机
.withBundleName("com.example.myapplication")//哪个应用
.withAbilityName("com.example.myapplication.Second_Ability")//哪个界面
.build();
i.setOperation(operation);
i.setParam("username","zhangsan");
i.setParam("userLevel","V8");
startAbility(i);
}
}
}
//第二个界面中的代码
public class Second_AbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_second_);
Text text = (Text) findComponentById(ResourceTable.Id_text_helloworld);
//通过键获取对应的值
String username = intent.getStringParam("username");
String userLevel = intent.getStringParam("userLevel");
//并把值设置到文本中
text.setText(username + "---" + userLevel);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
4.页面跳转的所有情况
同一个页面中,不同切片之间的跳转(无参,有参,有返回结果)
不同页面中,主切片跟主切片之间的跳转(无参,有参,有返回结果)
不同页面中,主切片跟非主切片之间的跳转(无参,有参,有返回结果)
代码示例:
同一个页面中,不同切片之间的跳转(无参,有参,有返回结果)
public class MainAbilitySlice extends AbilitySlice {
Button but1;
Button but2;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
but1 = (Button) findComponentById(ResourceTable.Id_but1);
but2 = (Button) findComponentById(ResourceTable.Id_but2);
but1.setClickedListener(this::onClick);
but2.setClickedListener(this::onClick);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
public void onClick(Component component) {
if (component == but1) {
//跳转页面
//创建一个意图对象。
Intent i = new Intent();
//创建意图的参数对象。
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")//本机
.withBundleName("com.example.myapplication5")//哪个应用
.withAbilityName("com.example.myapplication5.MainAbilitySecond")//哪个界面
.build();
i.setOperation(operation);
startAbility(i);
}else if(component == but2){
//跳转页面
//创建一个意图对象。
Intent i = new Intent();
//创建意图的参数对象。
Operation operation = new Intent.OperationBuilder()
.withAction("abilitysecond")
.build();
i.setOperation(operation);
startAbility(i);
}
}
}
不同页面的跳转
public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
Button but1;
Button but2;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
but1 = (Button) findComponentById(ResourceTable.Id_but1);
but2 = (Button) findComponentById(ResourceTable.Id_but2);
but1.setClickedListener(this);
but2.setClickedListener(this);
}
@Override
public void onClick(Component component) {
if(component == but1){
//就要跳转到第二个页面中的主要子界面中
//创建意图对象
Intent i = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("") //本机
.withBundleName("com.example.jumpapplication6")//跳转到哪个应用上
.withAbilityName("com.example.jumpapplication6.SecondAbility")//哪个页面
.build();
i.setOperation(operation);
startAbility(i);
}else if(component == but2){
//就要跳转到第二个页面中的其他子界面中
//创建意图对象
Intent i = new Intent();
Operation operation = new Intent.OperationBuilder()
.withAction("secondabilityslicenomain")
.build();
i.setOperation(operation);
startAbility(i);
}
}
}