鸿蒙开发之UI框架
一、Java UI框架
概述
Java UI框架提供了一部分Component和ComponentContainer的具体子类,即创建用户界面(UI)的各类组件(如:文本、按钮等)和常用的布局(如:DirectionalLayout和DependentLayout)。用户可通过组件进行交互操作,并获得响应。所有的UI操作都应该在主线程进行设置。
组件和布局
用户界面元素统称为组件,组件根据一定的层级结构进行组合形成布局。组件在未被添加到布局中时,既无法显示也无法交互,因此一个用户界面至少包含一个布局。
在UI框架中,具体的布局类通常以XXLayout命名,完整的用户界面是一个布局,用户界面中的一部分也可以是一个布局。布局中容纳Component与ComponentContainer对象。
Component和ComponentContainer
Component:提供内容显示,是界面中所有组件的基类,可以给Component设置事件处理回调来创建一个可交互的组件。JavaUI框架提供了一些常用的界面元素,也可称之为组件,组件一般直接继承Component或它的子类,如Text、Image等。
ComponentContainer:作为容器容纳Component或ComponentContainer对象,并对它们进行布局。Java UI框架提供了一些标准布局功能的容器,它们继承自ComponentContainer,一般以“Layout”结尾,如DirectionalLayout、DependentLayout等。
布局配置LayoutConfig
每种布局都根据自身特点提供LayoutConfig供子Component设定布局属性和参数,通过指定布局属性可以对子Component在布局中的显示效果进行约束。如:“width”、“height”是最基本的布局属性,指定了组件的大小。
组件树
布局把Component和ComponentContainer以树状的层级结构进行组织,这样的一个布局就称为组件树。组件树的特点是仅有一个根组件,其他组件有且仅有一个父节点,组件之间的关系受到父节点的规则约束。
二、常用布局
DirectionalLayout
DirectionalLayout是Java UI中的一种重要组件布局,用于将一组组件(Component)按照水平或者垂直方向排布,能够方便地对齐布局内的组件。
排列方向(orientation)
分为水平
(horizontal)或者垂直
(vertical)方向。使用orientation设置布局内组件的排列方式,默认为垂直排列。
1.垂直方向排列
垂直方向排列三个按钮
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_content"
ohos:orientation="vertical">
<Button
ohos:width="33vp"
ohos:height="20vp"
ohos:bottom_margin="3vp"
ohos:left_margin="13vp"
ohos:background_element="$graphic:color_cyan_element"
ohos:text="Button 1"/>
<Button
ohos:width="33vp"
ohos:height="20vp"
ohos:bottom_margin="3vp"
ohos:left_margin="13vp"
ohos:background_element="$graphic:color_cyan_element"
ohos:text="Button 2"/>
<Button
ohos:width="33vp"
ohos:height="20vp"
ohos:bottom_margin="3vp"
ohos:left_margin="13vp"
ohos:background_element="$graphic:color_cyan_element"
ohos:text="Button 3"/>
</DirectionalLayout>
color_cyan_element.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<solid
ohos:color="#00FFFD"/>
</shape>
2.水平方向排列
水平方向排列三个按钮
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_content"
ohos:orientation="horizontal">
<Button
ohos:width="33vp"
ohos:height="20vp"
ohos:left_margin="13vp"
ohos:background_element="$graphic:color_cyan_element"
ohos:text="Button 1"/>
<Button
ohos:width="33vp"
ohos:height="20vp"
ohos:left_margin="13vp"
ohos:background_element="$graphic:color_cyan_element"
ohos:text="Button 2"/>
<Button
ohos:width="33vp"
ohos:height="20vp"
ohos:left_margin="13vp"
ohos:background_element="$graphic:color_cyan_element"
ohos:text="Button 3"/>
</DirectionalLayout>
3.不会自动换行
DirectionalLayout不会自动换行,其子组件会按照设定的方向依次排列,若超过布局本身的大小,超出布局大小的部分将不会被显示
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="20vp"
ohos:orientation="horizontal">
<Button
ohos:width="166vp"
.....
ohos:text="Button 1"/>
<Button
ohos:width="166vp"
.....
ohos:text="Button 2"/>
<Button
ohos:width="166vp"
.....
ohos:text="Button 3"/>
</DirectionalLayout>
此布局包含了三个按钮,但由于DirectionalLayout不会自动换行,超出布局大小的组件部分无法显示。界面显示如下:
4.对齐方式
DirectionalLayout中的组件使用layout_alignment控制自身在布局中的对齐方式,当对齐方式与排列方式方向一致时,对齐方式不会生效,如设置了水平方向的排列方式,则左对齐、右对齐将不会生效。
参数 | 作用 | 可搭配排列方式 |
---|---|---|
left | 左对齐 | 垂直排列 |
top | 顶部对齐 | 水平排列 |
right | 右对齐 | 垂直排列 |
bottom | 底部对齐 | 水平排列 |
horizontal_center | 水平方向居中 | 垂直排列 |
vertical_center | 垂直方向居中 | 水平排列 |
center | 垂直与水平方向都居中 | 水平/垂直排列 |
三种对齐方式
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="60vp">
<Button
ohos:width="50vp"
ohos:height="20vp"
ohos:background_element="$graphic:color_cyan_element"
ohos:layout_alignment="left"
ohos:text="Button 1"/>
<Button
ohos:width="50vp"
ohos:height="20vp"
ohos:background_element="$graphic:color_cyan_element"
ohos:layout_alignment="horizontal_center"
ohos:text="Button 2"/>
<Button
ohos:width="50vp"
ohos:height="20vp"
ohos:background_element="$graphic:color_cyan_element"
ohos:layout_alignment="right"
ohos:text="Button 3"/>
</DirectionalLayout>
5.权重
权重(weight)就是按比例来分配组件占用父组件的大小,在水平布局下计算公式为:
父布局可分配宽度=父布局宽度-所有子组件width之和;
组件宽度=组件weight/所有组件weight之和*父布局可分配宽度;
实际使用过程中,建议使用width=0来按比例分配父布局的宽度,1:1:1效果如下:
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_content"
ohos:orientation="horizontal">
<Button
ohos:width="0vp"
ohos:height="20vp"
ohos:weight="1"
ohos:background_element="$graphic:color_cyan_element"
ohos:text="Button 1"/>
<Button
ohos:width="0vp"
ohos:height="20vp"
ohos:weight="1"
ohos:background_element="$graphic:color_gray_element"
ohos:text="Button 2"/>
<Button
ohos:width="0vp"
ohos:height="20vp"
ohos:weight="1"
ohos:background_element="$graphic:color_cyan_element"
ohos:text="Button 3"/>
</DirectionalLayout>
DependentLayout
DependentLayout与DirectionalLayout相比,拥有更多的排布方式,每个组件可以指定相对于其他同级元素的位置,或者指定相对于父组件的位置。
排列方式相对于其他
同级组件
或者父组件
的位置进行布局。
相对于同级组件
相对于同级组件的位置布局
位置布局|描述|
–|–|-|
above|处于同级组件的上侧。
below|处于同级组件的下侧。
start_of|处于同级组件的起始侧。
end_of|处于同级组件的结束侧。
left_of|处于同级组件的左侧。
right_of|处于同级组件的右侧。
相对于父组件
相对于父组件的位置布局
位置布局 | 描述 |
---|---|
align_parent_left | 处于父组件的左侧。 |
align_parent_right | 处于父组件的右侧。 |
align_parent_start | 处于父组件的起始侧。 |
align_parent_end | 处于父组件的结束侧。 |
align_parent_top | 处于父组件的上侧。 |
align_parent_bottom | 处于父组件的下侧。 |
center_in_parent | 处于父组件的中间。 |
示例
<?xml version="1.0" encoding="utf-8"?>
<DependentLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_content"
ohos:background_element="$graphic:color_background_gray_element">
<Text
ohos:id="$+id:text1"
ohos:width="match_parent"
ohos:height="match_content"
ohos:text_size="25fp"
ohos:top_margin="15vp"
ohos:left_margin="15vp"
ohos:right_margin="15vp"
ohos:background_element="$graphic:color_gray_element"
ohos:text="Title"
ohos:text_weight="1000"
ohos:text_alignment="horizontal_center"
/>
<Text
ohos:id="$+id:text2"
ohos:width="match_content"
ohos:height="120vp"
ohos:text_size="10vp"
ohos:background_element="$graphic:color_gray_element"
ohos:text="Catalog"
ohos:top_margin="15vp"
ohos:left_margin="15vp"
ohos:right_margin="15vp"
ohos:bottom_margin="15vp"
ohos:align_parent_left="true"
ohos:text_alignment="center"
ohos:multiple_lines="true"
ohos:below="$id:text1"
ohos:text_font="serif"/>
<Text
ohos:id="$+id:text3"
ohos:width="match_parent"
ohos:height="120vp"
ohos:text_size="25fp"
ohos:background_element="$graphic:color_gray_element"
ohos:text="Content"
ohos:top_margin="15vp"
ohos:right_margin="15vp"
ohos:bottom_margin="15vp"
ohos:text_alignment="center"
ohos:below="$id:text1"
ohos:end_of="$id:text2"
ohos:text_font="serif"/>
<Button
ohos:id="$+id:button1"
ohos:width="70vp"
ohos:height="match_content"
ohos:text_size="15fp"
ohos:background_element="$graphic:color_gray_element"
ohos:text="Previous"
ohos:right_margin="15vp"
ohos:bottom_margin="15vp"
ohos:below="$id:text3"
ohos:left_of="$id:button2"
ohos:italic="false"
ohos:text_weight="5"
ohos:text_font="serif"/>
<Button
ohos:id="$+id:button2"
ohos:width="70vp"
ohos:height="match_content"
ohos:text_size="15fp"
ohos:background_element="$graphic:color_gray_element"
ohos:text="Next"
ohos:right_margin="15vp"
ohos:bottom_margin="15vp"
ohos:align_parent_end="true"
ohos:below="$id:text3"
ohos:italic="false"
ohos:text_weight="5"
ohos:text_font="serif"/>
</DependentLayout>
color_background_gray_element.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<solid
ohos:color="#ffbbbbbb"/>
</shape>
color_gray_element.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<solid
ohos:color="#ffbbbbbb"/>
</shape>
TableLayout
TableLayout使用表格的方式划分子组件, 也就是行和列的方式。
TableLayout可配置表格的排列方式,行数和列数,以及组件的位置。
在XML文件中创建TableLayout
<?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:background_element="#87CEEB"
ohos:layout_alignment="horizontal_center"
ohos:padding="8vp">
</TableLayout>
在xml创建Text的背景table_text_bg_element.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="5vp"/>
<stroke
ohos:width="1vp"
ohos:color="gray"/>
<solid
ohos:color="#00BFFF"/>
</shape>
在TableLayout布局中添加组件
<?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:background_element="#87CEEB"
ohos:layout_alignment="horizontal_center"
ohos:padding="8vp">
<Text
ohos:height="60vp"
ohos:width="60vp"
ohos:background_element="$graphic:table_text_bg_element.xml"
ohos:margin="8vp"
ohos:text="1"
ohos:text_alignment="center"
ohos:text_size="20fp"/>
<Text
ohos:height="60vp"
ohos:width="60vp"
ohos:background_element="$graphic:table_text_bg_element.xml"
ohos:margin="8vp"
ohos:text="2"
ohos:text_alignment="center"
ohos:text_size="20fp"/>
<Text
ohos:height="60vp"
ohos:width="60vp"
ohos:background_element="$graphic:table_text_bg_element.xml"
ohos:margin="8vp"
ohos:text="3"
ohos:text_alignment="center"
ohos:text_size="20fp"/>
<Text
ohos:height="60vp"
ohos:width="60vp"
ohos:background_element="$graphic:table_text_bg_element.xml"
ohos:margin="8vp"
ohos:text="4"
ohos:text_alignment="center"
ohos:text_size="20fp"/>
</TableLayout>
默认一列多行
设置行数和列数
ohos:row_count表示设置网格布局中行数,ohos:column_count表示设置网格布局中的列数。如果没有为子布局设置行列数,则自动继承父布局的行数和列数。在网格布局中若子组件的数量超出列数设置,则会自动添加行数。比如下列代码,我们设置一行,两列,但是是三个子组件,行数设置失效,会自动增加一行。
<TableLayout
...
ohos:row_count="2"
ohos:column_count="2">
设置对齐方式
属性值 | 效果 |
---|---|
align_edges | 表示子组件边界对齐,默认对齐方式。 |
align_contents | 表示子组件边距对齐。 |
<TableLayout
...
ohos:alignment_type="align_contents">
...
</TableLayout>
StackLayout
StackLayout直接在屏幕上开辟出一块空白的区域,添加到这个布局中的视图都是以层叠的方式显示,而它会把这些视图默认放到这块区域的左上角,第一个添加到布局中视图显示在最底层,最后一个被放在最顶层。上一层的视图会覆盖下一层的视图。
StackLayout中组件的布局默认在区域的左上角,并且以后创建的组件会在上层
<?xml version="1.0" encoding="utf-8"?>
<StackLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:id="$+id:stack_layout"
ohos:height="match_parent"
ohos:width="match_parent">
<Text
ohos:id="$+id:text_blue"
ohos:text_alignment="bottom|horizontal_center"
ohos:text_size="24fp"
ohos:text="第一层"
ohos:height="400vp"
ohos:width="400vp"
ohos:background_element="#3F56EA" />
<Text
ohos:id="$+id:text_light_purple"
ohos:text_alignment="bottom|horizontal_center"
ohos:text_size="24fp"
ohos:text="第二层"
ohos:height="300vp"
ohos:width="300vp"
ohos:background_element="#00AAEE" />
<Text
ohos:id="$+id:text_orange"
ohos:text_alignment="center"
ohos:text_size="24fp"
ohos:text="第三层"
ohos:height="80vp"
ohos:width="80vp"
ohos:background_element="#00BFC9" />
</StackLayout>
三、常用组件
组件分类
根据组件的功能,可以将组件分为布局类、显示类、交互类三类:
组件类别|组件名称|功能描述|
–|–|–|–|
布局类|PositionLayout、DirectionalLayout、StackLayout、DependentLayout、TableLayout、AdaptiveBoxLayout|提供了不同布局规范的组件容器,例如以单一方向排列的DirectionalLayout、以相对位置排列的DependentLayout、以确切位置排列的PositionLayout等。
|显示类|Text、Image、Clock、TickTimer、ProgressBar|提供了单纯的内容显示,例如用于文本显示的Text,用于图像显示的Image等。
|交互类|TextField、Button、Checkbox、RadioButton/RadioContainer、Switch、ToggleButton、Slider、Rating、ScrollView、TabList、ListContainer、PageSlider、PageFlipper、PageSliderIndicator、Picker、TimePicker、DatePicker、SurfaceProvider、ComponentProvider|提供了具体场景下与用户交互响应的功能,例如Button提供了点击响应功能,Slider提供了进度选择功能等。
Text
Text是用来显示字符串的组件,在界面上显示为一块文本区域。Text作为一个基本组件,有很多扩展,常见的有按钮组件Button,文本编辑组件TextField。
创建Text
在layout目录下的xml文件中创建Text。
<Text
ohos:id="$+id:text"
ohos:width="match_content"
ohos:height="match_content"
ohos:text="Text"/>
创建背景
常用的背景如常见的文本背景、按钮背景,可以采用XML格式放置在graphic目录下。如:创建“background_text.xml”,在background_text.xml中定义文本的背景。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle"> //背景形状,oval椭圆,rectangle方形...
<corners
ohos:radius="20"/> //背景圆角程度
<solid
ohos:color="#878787"/>//背景颜色
</shape>
设置Text
在xml中设置Text的背景。
<Text
...
ohos:background_element="$graphic:background_text"/>
字体大小,颜色,边距
ohos:text_size="28fp"
ohos:text_color="blue"
ohos:left_margin="15vp"
ohos:bottom_margin="15vp"
ohos:right_padding="15vp"
ohos:left_padding="15vp"
设置字体风格和字重
ohos:italic="true"
ohos:text_weight="700"
ohos:text_font="serif"
设置文本对齐方式
ohos:text_alignment="horizontal_center|bottom"
设置文本换行和最大显示行数
ohos:multiple_lines="true"
ohos:max_text_lines="2"
自动调节字体大小
Text对象支持根据文本长度自动调整文本的字体大小和换行。
1.设置自动换行、最大显示行数和自动调节字体大小。
<Text
ohos:id="$+id:text"
ohos:width="90vp"
ohos:height="match_content"
ohos:min_height="30vp"
ohos:text="T"
ohos:text_color="#0000FF"
ohos:italic="true"
ohos:text_weight="700"
ohos:text_font="serif"
ohos:multiple_lines="true"
ohos:max_text_lines="1"
ohos:auto_font_size="true"
ohos:right_padding="8vp"
ohos:left_padding="8vp"
ohos:background_element="$graphic:background_text"/>
2.通过setAutoFontSizeRule设置自动调整规则,三个入参分别是最小的字体大小、最大的字体大小、每次调整文本字体大小的步长。
Text text = (Text) findComponentById(ResourceTable.Id_text);
// 设置自动调整规则
text.setAutoFontSizeRule(30, 100, 1);
// 设置点击一次增多一个"T"
text.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component Component) {
text.setText(text.getText() + "T");
}
});
跑马灯效果
当文本过长时,可以设置跑马灯效果,实现文本滚动显示。前提是文本换行关闭且最大显示行数为1,默认情况下即可满足前提要求。
// 跑马灯效果
text.setTruncationMode(Text.TruncationMode.AUTO_SCROLLING);
// 启动跑马灯效果
text.startAutoScrolling();
响应点击事件
为Text对象添加一个点击事件,然后自定义响应点击事件的方法。如:通过创建一个Component.ClickedListener对象,然后通过调用setClickedListener将其分配给Text。
Text text = (Text)findComponentById(ResourceTable.Id_text_helloworld);
// 为按钮设置点击事件回调
text.setClickedListener(component->{
// 此处添加点击按钮后的事件处理逻辑
});
Button
Button是一种常见的组件,点击可以触发对应的操作,通常由文本或图标组成,也可以由图标和文本共同组成。
创建Button
在layout目录下的xml文件中创建Button,可以设置按钮的形状、颜色等。
<Button
ohos:id="$+id:button"
ohos:width="match_content"
ohos:height="match_content"
ohos:text_size="27fp"
ohos:text="button"
ohos:background_element="$graphic:background_button"
ohos:left_margin="15vp"
ohos:bottom_margin="15vp"
ohos:right_padding="8vp"
ohos:left_padding="8vp"
ohos:element_left="$graphic:ic_btn_reload"
/>
graphic目录下xml文件(例:background_button.xml)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="10"/>
<solid
ohos:color="#007CFD"/>
</shape>
矢量图的转换
ic_btn_reload.xml:是一个矢量图,IED可以自动转换为xml文件,然后使用。
在graphic目录右键New => Svg To Xml => 然后选择Svg图标即可将Svg图标转换成xml文件。
ohos:element_left="$graphic:ic_btn_reload"
不同类型的按钮
按照按钮的形状,按钮可以分为:普通按钮,椭圆按钮,胶囊按钮,圆形按钮等。
1.普通按钮
普通按钮和其他按钮的区别在于不需要设置任何形状,只设置文本和背景颜色
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<solid
ohos:color="#007CFD"/>
</shape>
2.椭圆按钮
椭圆按钮是通过设置background_element的来实现的,background_element的shape设置为椭圆(oval)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="oval">
<solid
ohos:color="#007CFD"/>
</shape>
ohos:background_element="$graphic:oval_button_element"
3.胶囊按钮
胶囊按钮是一种常见的按钮,设置按钮背景时将背景设置为矩形形状,并且设置ShapeElement的radius的半径
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="100"/>
<solid
ohos:color="#007CFD"/>
</shape>
ohos:background_element="$graphic:capsule_button_element"
4.圆形按钮
圆形按钮和椭圆按钮的区别在于组件本身的宽度和高度需要相同
ohos:width="50vp"
ohos:height="50vp"
ohos:background_element="$graphic:circle_button_element"
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="oval">
<solid
ohos:color="#007CFD"/>
</shape>
响应点击事件
用户点击按钮时,Button对象将收到一个点击事件,然后自定义响应点击事件的方法。如:通过创建一个Component.ClickedListener对象,然后通过调用setClickedListener将其分配给按钮。
Button button = (Button) findComponentById(ResourceTable.Id_button);
// 为按钮设置点击事件回调
button.setClickedListener(new Component.ClickedListener() {
public void onClick(Component v) {
// 此处添加点击按钮后的事件处理逻辑
}
});
TextField
TextField提供了一种文本输入框。
创建TextField
<TextField
...
ohos:height="40vp"
ohos:width="200vp"
ohos:left_padding="20vp"
/>
获取输入框的内容
String getContent = textField.getText();
设置TextField
<TextField
...
ohos:background_element="$graphic:background_text_field"
/>
graphic目录下xml文件(例:background_text_field.xml)
<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="40"/>
<solid
ohos:color="#FFFFFF"/>
</shape>
设置提示文字
ohos:hint="Enter phone number or email"/>
设置内边距
<TextField
...
ohos:left_padding="24vp"
ohos:right_padding="24vp"
ohos:top_padding="8vp"
ohos:bottom_padding="8vp"/>
设置多行显示
ohos:multiple_lines="true"/>
设置不可用状态
通过TextField的Enable属性来控制文本框是否可用,当设置成false后,文本框不再能被输入。
TextField textField = (TextField) findComponentById(ResourceTable.Id_text_field);
textField.setEnabled(false);
响应焦点变化
textField.setFocusChangedListener(((component, isFocused) -> {
if (isFocused) {
// 获取到焦点
...
}else {
// 失去焦点
...
}
}));
设置基线
ohos:basement="#000099"
Image
Image是用来显示图片的组件。
创建Image
在src > main > resources > base > media”,添加一个图片至media文件夹下,既可以在XML中创建Image,也可以在代码中创建Image
在XML中创建Image
<Image
ohos:id="$+id:image"
ohos:width="match_content"
ohos:height="match_content"
ohos:layout_alignment="center"
ohos:image_src="$media:plant"/>
在代码中创建Image
Image image = new Image(getContext());
image.setPixelMap(ResourceTable.Media_plant);
使用Image
设置透明度
ohos:image_src="$media:plant"
ohos:alpha="0.5"
设置缩放系数
ohos:image_src="$media:plant"
ohos:scale_x="0.5"
ohos:scale_y="0.5"
设置缩放方式
当图片尺寸与Image尺寸不同时,可以根据不同的缩放方式来对图片进行缩放,如设置Image的宽高为200vp。以按比例缩小居中显示为例,设置ohos:scale_mode=“zoom_center”
缩放方式 | 值 |
---|---|
按比例将原图扩大(缩小)到Image的宽度,居中显示。 | zoom_center |
按比例将原图扩大(缩小)到Image的宽度,显示在Image的上部分位置。 | zoom_start |
按比例将原图扩大(缩小)到Image的宽度,显示在Image的下部分位置。 | zoom_end |
不按比例将图片扩大/缩小到Image的大小显示。 | stretch |
保持原图的大小,显示在Image的中心。当原图的尺寸大于Image的尺寸时,超过部分裁剪处理。 | center |
按比例将原图缩小到Image的宽度,将图片的内容完整居中显示。 | inside |
按比例将原图扩大(缩小)到Image的宽度和高度中较大的值。如设置的高度值较大时,在垂直方向上完整显示,水平方向上超出Image宽度的部分裁剪处理。 | clip_center |
ohos:image_src="$media:plant"
ohos:scale_mode="zoom_center"
设置裁剪对齐模式
当Image尺寸小于图片尺寸时,可以对图片进行裁剪,仍以Image的宽高为200vp为例,小于图片尺寸。以左对齐裁剪为例,设置clip_alignment=“256”
裁剪方式 | 值 |
---|---|
左对齐裁剪。 | left |
右对齐裁剪。 | right |
顶部对齐裁剪。 | top |
底部对齐裁剪。 | bottom |
居中裁剪。 | center |
ohos:image_src="$media:plant"
ohos:clip_alignment="256"
TabList和Tab
Tablist可以实现多个页签栏的切换,Tab为某个页签。子页签通常放在内容区上方,展示不同的分类。页签名称应该简洁明了,清晰描述分类的内容。
Picker
Picker提供了滑动选择器,允许用户从预定义范围中进行选择。
DatePicker
DatePicker主要供用户选择日期。
TimePicker
TimePicker主要供用户选择时间。
Switch
Switch是切换单个设置开/关两种状态的组件。
RadioButton
RadioButton用于多选一的操作,需要搭配RadioContainer使用,实现单选效果。
创建RadioButton
<RadioButton
ohos:id="$+id:rb_1"
ohos:height="40vp"
ohos:width="match_content"
ohos:text="A.Learning"
ohos:text_size="20fp"/>
设置RadioButton
设置单选按钮的字体颜色
在xml中设置:text_color_on为选中状态的字体颜色,text_color_off为未选中状态的字体颜色
<RadioButton
...
ohos:text_color_on="#00BFFF"
ohos:text_color_off="#808080"/>
在Java代码中设置
rBtn.setTextColorOn(new Color(Color.getIntColor("#0066FF")));
rBtn.setTextColorOff(new Color(Color.getIntColor("#505050")));
监听事件
//监听方在RadioContainer身上
RadioContainer rc = (RadioContainer) findComponentById(ResourceTable.Id_rc_sex);
rc.setMarkChangedListener(new RadioContainer.CheckedStateChangedListener() {
@Override
public void onCheckedChanged(RadioContainer radioContainer, int i) {
//i是radioButton的索引,从0开始
RadioButton rb = (RadioButton) radioContainer.getComponentAt(i);
String s = rb.getText().toString();
new ToastDialog(MainAbilitySlice.this).setText(s).show();
}
});
RadioContainer
RadioContainer是RadioButton的容器,在其包裹下的RadioButton保证只有一个被选项。
Checkbox
Checkbox可以实现选中和取消选中的功能。
创建Checkbox
<Checkbox
ohos:id="$+id:check_box"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="This is a checkbox"
ohos:text_size="20fp" />
设置Checkbox
ohos:check_element="$graphic:background_checkbox_check"
<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="oval">
<solid
ohos:color="#00FFCC"/>
</shape>
Java代码设置Checkbox在选中与取消选中时的背景
ShapeElement elementButtonOn = new ShapeElement();
elementButtonOn.setRgbColor(RgbPalette.RED);
elementButtonOn.setShape(ShapeElement.RECTANGLE);
elementButtonOn.setCornerRadius(0.0f);
ShapeElement elementButtonOff = new ShapeElement();
elementButtonOff.setRgbColor(RgbPalette.BLACK);
elementButtonOff.setShape(ShapeElement.RECTANGLE);
elementButtonOff.setCornerRadius(0.0f);
StateElement checkElement = new StateElement();
checkElement.addState(new int[]{ComponentState.COMPONENT_STATE_CHECKED}, elementButtonOn);
checkElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, elementButtonOff);
Checkbox checkbox = (Checkbox) findComponentById(ResourceTable.Id_check_box);
checkbox.setButtonElement(checkElement);
设置Checkbox的文字在选中和取消选中时的颜色
ohos:text_color_on="#00AAEE"
ohos:text_color_off="#000000"
设置选中状态
checkbox.setChecked(true);
设置不同状态之间的切换
如果当前为选中状态,那么将变为未选中;如果当前是未选中状态,将变为选中状态。
checkbox.toggle();
设置响应Checkbox状态变更的事件
// state表示是否被选中
checkbox.setCheckedStateChangedListener((view, state) -> {
// 状态改变的逻辑
...
});
ProgressBar
ProgressBar用于显示内容或操作的进度。
创建ProgressBar
<ProgressBar
ohos:progress_width="10vp"
ohos:height="60vp"
ohos:width="600vp"
ohos:max="100"
ohos:min="0"
ohos:progress="60"/>
设置ProgressBar方向为垂直
ohos:orientation="vertical"
设置当前进度
ohos:progress="60"
progressBar.setProgressValue(60);
设置最大和最小值
ohos:max="400"
ohos:min="0"
progressBar.setMaxValue(400);
progressBar.setMinValue(0);
设置进度颜色
ohos:progress_element="#FF9900"
设置底色颜色
ohos:background_instruct_element="#FFFFFF"
设置分割线
ohos:divider_lines_enabled="true"
ohos:divider_lines_number="5"
progressBar.enableDividerLines(true);
progressBar.setDividerLinesNumber(5);
设置分割线颜色
progressBar.setDividerLineColor(Color.MAGENTA);
设置提示文字
ohos:progress_hint_text="20%"
ohos:progress_hint_text_color="#FFCC99"
事件改变进度值
ProgressBar progressBar = (ProgressBar) findComponentById(ResourceTable.Id_my_pgb);
progressBar.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
ProgressBar pgb = (ProgressBar) component;
pgb.setProgressValue(pgb.getProgress()+5);
}
});
RoundProgressBar
RoundProgressBar继承自ProgressBar,拥有ProgressBar的属性,在设置同样的属性时用法和ProgressBar一致,用于显示环形进度。
ToastDialog
ToastDialog是在窗口上方弹出的对话框,是通知操作的简单反馈。ToastDialog会在一段时间后消失,在此期间,用户还可以操作当前窗口的其他组件。
创建ToastDialog
new ToastDialog(getContext())
.setText("This is a ToastDialog")
.show();
设置其他属性
ToastDialog toastDialog = new ToastDialog(this);
//设置位置
toastDialog.setAlignment(LayoutAlignment.CENTER);
//大小
toastDialog.setSize(MATCH_CONTENT, MATCH_CONTENT);
//显示事件
toastDialog.setDuration(durationTime);
//自动关闭
toastDialog.setAutoClosable(true);
自定义ToastDialog的Component
DirectionalLayout toastLayout = (DirectionalLayout) LayoutScatter.getInstance(this)
.parse(ResourceTable.Layout_layout_toast, null, false);
new ToastDialog(getContext())
.setComponent(toastLayout)
.setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT)
.setAlignment(LayoutAlignment.CENTER)
.show();
layout_toast.xml布局
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_content"
ohos:width="match_content"
ohos:orientation="vertical">
<Text
ohos:id="$+id:msg_toast"
ohos:height="match_content"
ohos:width="match_content"
ohos:left_padding="16vp"
ohos:right_padding="16vp"
ohos:top_padding="4vp"
ohos:bottom_padding="4vp"
ohos:layout_alignment="center"
ohos:text_size="16fp"
ohos:text="This is a ToastDialog for the customized component"
ohos:background_element="$graphic:background_toast_element"/>
</DirectionalLayout>
background_toast_element.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="30vp"/>
<solid
ohos:color="#66808080"/>
</shape>
ScrollView
ScrollView是一种带滚动功能的组件,它采用滑动的方式在有限的区域内显示更多的内容。
创建ScrollView
<ScrollView
ohos:id="$+id:scrollview"
ohos:height="300vp"
ohos:width="300vp"
ohos:background_element="#FFDEAD"
ohos:top_margin="32vp"
ohos:bottom_padding="16vp"
ohos:layout_alignment="horizontal_center">
<DirectionalLayout
ohos:height="match_content"
ohos:width="match_content">
<Image
ohos:id="$+id:img_1"
ohos:width="300vp"
ohos:height="match_content"
ohos:top_margin="16vp"
ohos:image_src="$media:dog.png"/>
<!-- 放置任意需要展示的组件-->
...
</DirectionalLayout>
</ScrollView>
ListContainer
ListContainer是用来呈现连续、多行数据的组件,包含一系列相同类型的列表项。
在layout目录下的xml文件中创建ListContainer
<?xml version="1.0" encoding="utf-8"?>
<ListContainer
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:id="$+id:list_container"
ohos:height="200vp"
ohos:width="300vp"
ohos:layout_alignment="horizontal_center"/>
在layout目录下新建xml文件(例:item_sample.xml),作为ListContainer的子布局。
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_content"
ohos:width="match_parent"
ohos:left_margin="16vp"
ohos:right_margin="16vp"
ohos:orientation="vertical">
<Text
ohos:id="$+id:item_index"
ohos:height="match_content"
ohos:width="match_content"
ohos:padding="4vp"
ohos:text="Item0"
ohos:text_size="20fp"
ohos:layout_alignment="center"/>
</DirectionalLayout>
创建SampleItem.java,作为ListContainer的数据包装类。
public class SampleItem {
private String name;
public SampleItem(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ListContainer每一行可以为不同的数据,因此需要适配不同的数据结构,使其都能添加到ListContainer上。创建SampleItemProvider.java,继承自RecycleItemProvider。
方法 | 作用 |
---|---|
int getCount() | 返回填充的表项个数。 |
Object getItem(int position) | 根据position返回对应的数据。 |
long getItemId(int position) | 返回某一项的id。 |
Component getComponent(int position, Component covertComponent,ComponentContainer componentContainer) | 根据position返回对应的界面组件。 |
public class SampleItemProvider extends RecycleItemProvider {
//把数据封装在SampleItem对象的list里
private List<SampleItem> list;
//传入一个AbilitySlice
private AbilitySlice slice;
//构造器初始化属性
public SampleItemProvider(List<SampleItem> list, AbilitySlice slice) {
this.list = list;
this.slice = slice;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/**
* @param position 组件在数据集里的位置
* @param convertComponent 要重用的前一个组件
* @param componentContainer 获取的组件的父组件
* @return 实现getComponent需要item的布局,自己创建item_sample
*/
@Override
public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
Component component = convertComponent;
if (component == null) {
component = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item_sample, null, false);
}
SampleItem sampleItem = list.get(position);
Text text = (Text) component.findComponentById(ResourceTable.Id_item_index);
text.setText(sampleItem.getName());
return component;
}
}
添加ListContainer的数据,并适配其数据结构。
public class MainAbilitySlice extends AbilitySlice{
static final HiLogLabel LOG_LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00002, "MainAbilitySlice");
@Override
public void onStart(Intent intent) {
HiLog.info(LOG_LABEL, "--------onStart2");
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ListContainer);
//初始化
initListContainer();
};
/**
* 初始化布局以及加载数据
*/
private void initListContainer() {
ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_container);
List<SampleItem> list = getData();
SampleItemProvider sampleItemProvider = new SampleItemProvider(list,this,this);
listContainer.setItemProvider(sampleItemProvider);
}
/**
* 构造数据
* @return
*/
private ArrayList<SampleItem> getData() {
ArrayList<SampleItem> list = new ArrayList<>();
for (int i = 0; i <= 18; i++) {
list.add(new SampleItem("Item"+i));
}
return list;
}
}
设置响应点击事件。
SampleItemProvider添加接口并设置初始化
//list中的每个SampleItem被点击的时候触发,需要自己新建接口
private ItemClickedListener linstener;
//构造器初始化属性
public SampleItemProvider(List<SampleItem> list, AbilitySlice slice, ItemClickedListener linstener) {
this.list = list;
this.slice = slice;
this.linstener = linstener;
}
/**
* 设置响应点击事件接口
*/
public interface ItemClickedListener {
void itemClick(SampleItem sampleItem);
}
修改getComponent()方法
/**
* @param position 组件在数据集里的位置
* @param convertComponent 要重用的前一个组件
* @param componentContainer 获取的组件的父组件
* @return 实现getComponent需要item的布局,自己创建item_sample
*/
@Override
public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
Component component = convertComponent;
if (component == null) {
component = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item_sample, null, false);
}
SampleItem sampleItem = list.get(position);
Text text = (Text) component.findComponentById(ResourceTable.Id_item_index);
text.setText(sampleItem.getName());
text.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
linstener.itemClick(sampleItem);
}
});
return component;
}
继承SampleItemProvider.ItemClickedListener接口并重新其方法
public class MainAbilitySlice extends AbilitySlice implements SampleItemProvider.ItemClickedListener{
@Override
public void itemClick(SampleItem sampleItem) {
new ToastDialog(getContext())
.setText("clicked:"+sampleItem.getName())
// Toast显示在界面中间
.setAlignment(LayoutAlignment.CENTER)
.show();
}
}
设置点击事件(二)
该方式不需要自定义接口,目前使用时发现有问题
text.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
ListContainer listContainer = (ListContainer) componentContainer.findComponentById(ResourceTable.Id_list_container);
listContainer.setItemClickedListener(new ListContainer.ItemClickedListener() {
@Override
public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
SampleItem item = (SampleItem) listContainer.getItemProvider().getItem(position);
new ToastDialog(slice.getContext())
.setText("clicked:"+item.getName())
// Toast显示在界面中间
.setAlignment(LayoutAlignment.CENTER)
.show();
}
});
}
});
ListContainer的样式设置
属性 | Java方法 | 作用 |
---|---|---|
orientation | setOrientation(int orientation) | 设置布局方向 |
– | setContentStartOffSet(int startOffset) setContentEndOffSet(int endOffset) setContentOffSet(int startOffset, int endOffset) | 设置列表容器的开始和结束偏移量 |
rebound_effect | setReboundEffect(boolean enabled) | 设置是否启用回弹效果 |
– | setReboundEffectParams(int overscrollPercent, float overscrollRate, int remainVisiblePercent)setReboundEffectParams(ListContainer.ReboundEffectParams reboundEffectParams) | 设置回弹效果参数 |
shader_color | setShaderColor(Color color) | 设置着色器颜色 |
设置布局方向
orientation设置为“horizontal”,表示横向布局;orientation设置为“vertical”,表示纵向布局。默认为纵向布局。
ohos:orientation="horizontal"
listContainer.setOrientation(Component.HORIZONTAL);
设置开始和结束偏移量
listContainer.setContentOffSet(32,16);
设置回弹效果
ohos:rebound_effect="true"
PageSlider
PageSlider是一个交互类组件.
main_pageSlider.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:background_element="blue"
ohos:orientation="vertical">
<PageSlider
ohos:id="$+id:pager_slider"
ohos:height="0vp"
ohos:width="match_parent"
ohos:background_element="#ffffff"
ohos:weight="1"/>
<RadioContainer
ohos:id="$+id:radio_container"
ohos:height="60vp"
ohos:width="match_parent"
ohos:alignment="horizontal_center"
ohos:orientation="horizontal">
<RadioButton
ohos:height="match_parent"
ohos:width="match_content"
ohos:text_size="20fp"
/>
<RadioButton
ohos:height="match_parent"
ohos:width="match_content"
ohos:text_size="20fp"
/>
</RadioContainer>
</DirectionalLayout>
pageSlider1.xml
<?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:height="match_content"
ohos:width="match_content"
ohos:center_in_parent="true"
ohos:text="PageSlider1"
ohos:text_size="25fp"/>
</DependentLayout>
在AbiltiySlice里使用
public class MainAbilitySlice extends AbilitySlice {
static final HiLogLabel LOG_LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00002, "MainAbilitySlice");
private RadioContainer radioContainer;
private PageSlider pageSlider;
private List<Component> pageviews;
@Override
public void onStart(Intent intent) {
HiLog.info(LOG_LABEL, "--------onStart2");
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_main_pageSlider);
radioContainer = (RadioContainer) findComponentById(ResourceTable.Id_radio_container);
((RadioButton) radioContainer.getComponentAt(0)).setChecked(true);
pageSlider = (PageSlider) findComponentById(ResourceTable.Id_pager_slider);
LayoutScatter layoutScatter = LayoutScatter.getInstance(getContext());
DependentLayout dependentLayout1 = (DependentLayout) layoutScatter.parse(ResourceTable.Layout_pageSlider1, null, false);
DependentLayout dependentLayout2 = (DependentLayout) layoutScatter.parse(ResourceTable.Layout_pageSlider2, null, false);
//将view装入数组
pageviews = new ArrayList<Component>();
pageviews.add(dependentLayout1);
pageviews.add(dependentLayout2);
//绑定适配器
pageSlider.setProvider(new PageSliderProvider() {
@Override
//获取当前窗体界面数
public int getCount() {
HiLog.info(LOG_LABEL, "--------getCount");
return pageviews.size();
}
//返回一个对象,这个对象表明了PagerAdapter适配器选择哪个对象放在当前的pageviews中
@Override
public Object createPageInContainer(ComponentContainer componentContainer, int i) {
componentContainer.addComponent(pageviews.get(i));
HiLog.info(LOG_LABEL, "--------createPageInContainer");
return pageviews.get(i);
}
//是从ViewGroup中移出当前View
@Override
public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
((PageSlider) componentContainer).removeComponent(pageviews.get(i));
HiLog.info(LOG_LABEL, "--------destroyPageFromContainer");
}
//断是否由对象生成界面
@Override
public boolean isPageMatchToObject(Component component, Object o) {
HiLog.info(LOG_LABEL, "--------isPageMatchToObject");
return component == o;
}
});
pageSlider.addPageChangedListener(new PageSlider.PageChangedListener() {
@Override
public void onPageSliding(int i, float v, int i1) {
//v:指示页面的位置偏移量。值的范围是(0,1]。
// 0表示正在显示目标页面。
//i1:指示显示页面的位置偏移像素数。
}
@Override
public void onPageSlideStateChanged(int i) {
HiLog.info(LOG_LABEL, "--------onPageSlideStateChanged");
}
@Override
public void onPageChosen(int i) {
((RadioButton) radioContainer.getComponentAt(i)).setChecked(true);
}
});
radioContainer.setMarkChangedListener((radioContainer, i) -> pageSlider.setCurrentPage(i));
}
}
四、布局与组件的使用
HarmonyOS提供了Ability和AbilitySlice两个基础类。有界面的Ability绑定了系统的Window进行UI展示,且具有生命周期。AbilitySlice主要用于承载Ability的具体逻辑实现和界面UI,是应用显示、运行和跳转的最小单元。AbilitySlice通过setUIContent为界面设置布局。
//设置界面入口,root为界面组件树根节点。
setUIContent(ComponentContainer root)
AbilitySlice的UI接口
接口声明 | 接口描述 |
---|---|
setUIContent(ComponentContainer root) | 设置界面入口,root为界面组件树根节点。 |
在Java UI框架中,提供了两种编写布局的方式,这两种方式创建出的布局没有本质差别。
1.在代码中创建布局:
用代码创建Component和ComponentContainer对象,为这些对象设置合适的布局参数和属性值,并将Component添加到ComponentContainer中,从而创建出完整界面。
2.在XML中声明UI布局:
按层级结构来描述Component和ComponentContainer的关系,给组件节点设定合适的布局参数和属性值,代码中可直接加载生成此布局。
1.XML创建布局
XML声明布局的方式更加简便直观。每一个Component和ComponentContainer对象大部分属性都支持在XML中进行设置,它们都有各自的XML属性列表。某些属性仅适用于特定的组件,例如:只有Text支持“text_color”属性,但不支持该属性的组件如果添加了该属性,该属性则会被忽略。具有继承关系的组件子类将继承父类的属性列表,Component作为组件的基类,拥有各个组件常用的属性,比如:ID、布局参数等。
ID
ohos:id="$+id:text"
在XML中使用此格式声明一个对开发者友好的ID,在编译过程中转换成一个常量。尤其在DependentLayout布局中,组件之间需要描述相对位置关系,描述时要通过ID来指定对应组件。
布局中的组件通常要设置独立的ID,以便在程序中查找该组件。如果布局中有不同组件设置了相同的ID,在通过ID查找组件时会返回查找到的第一个组件,因此尽量保证在所要查找的布局中为组件设置独立的ID值,避免出现与预期不符合的问题。
布局参数
ohos:width="20vp"
ohos:height="10vp"
具体的数值:10(以像素为单位)、10vp(以屏幕相对像素为单位)。
match_parent:表示组件大小将扩展为父组件允许的最大值,它将占据父组件方向上的剩余大小。
match_content:表示组件大小与它的内容占据的大小范围相适应。
方式一
修改ability_main.xml
打开layout下面的“ability_main.xml”文件,创建一个文本和一个按钮
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_parent"
ohos:orientation="vertical"
ohos:padding="32">
<Text
ohos:id="$+id:text"
ohos:width="match_content"
ohos:height="match_content"
ohos:layout_alignment="horizontal_center"
ohos:text="My name is Text."
ohos:text_size="25vp"/>
<Button
ohos:id="$+id:button"
ohos:margin="50"
ohos:width="match_content"
ohos:height="match_content"
ohos:layout_alignment="horizontal_center"
ohos:background_element="$graphic:background_button"
ohos:text="My name is Button."
ohos:text_size="50"/>
</DirectionalLayout>
创建按钮的背景
按钮的背景是通过“background_button”来指定的。右键点击“graphic”文件夹,选择“New > File”,命名为“background_button.xml”。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="10"/>
<solid
ohos:color="#007CFD"/>
</shape>
启动测试
方式二
创建XML布局文件
1.在DevEco Studio的“Project”窗口,打开“entry > src > main > resources > base”,右键点击“layout”文件夹,选择“New > File”,命名为“first_layout.xml”。
2.打开新创建的first_layout.xml布局文件,修改其中的内容,对布局和组件的属性和层级进行描述
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_parent"
ohos:orientation="vertical"
ohos:padding="32">
<Text
ohos:id="$+id:text"
ohos:width="match_content"
ohos:height="match_content"
ohos:layout_alignment="horizontal_center"
ohos:text="My name is Text."
ohos:text_size="25vp"/>
<Button
ohos:id="$+id:button"
ohos:margin="50"
ohos:width="match_content"
ohos:height="match_content"
ohos:layout_alignment="horizontal_center"
ohos:text="My name is Button."
ohos:text_size="50"/>
</DirectionalLayout>
加载XML布局
在代码中需要加载XML布局,并添加为根布局或作为其他布局的子Component。
package com.example.myapplication.slice;
import com.example.myapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.element.ShapeElement;
public class ExampleAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
// 加载XML布局作为根布局
super.setUIContent(ResourceTable.Layout_first_layout);
Button button = (Button) findComponentById(ResourceTable.Id_button);
if (button != null) {
// 设置组件的属性
ShapeElement background = new ShapeElement();
background.setRgbColor(new RgbColor(0, 125, 255));
background.setCornerRadius(25);
button.setBackground(background);
button.setClickedListener(new Component.ClickedListener() {
@Override
// 在组件中增加对点击事件的检测
public void onClick(Component Component) {
// 此处添加按钮被点击需要执行的操作
}
});
}
}
}
设置界面入口
public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(ExampleAbilitySlice.class.getName());
}
}
启动测试
2.代码创建布局
创建Ability
生成如下文件
设置界面入口
public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
//super.setMainRoute(MainAbilitySlice.class.getName());
super.setMainRoute(MyAbilitySlice.class.getName());
}
}
编写界面
设置组件大小的方法有两种:
通过setWidth/setHeight直接设置宽高。
通过setLayoutConfig方法设置布局属性来设定宽高。
区别:
setLayoutConfig增加更多的布局属性设置
两种方法设置的宽高以最后设置的作为最终结果。
取值:
具体以像素为单位的数值。
MATCH_PARENT:表示组件大小将扩展为父组件允许的最大值,它将占据父组件方向上的剩余大小。
MATCH_CONTENT:表示组件大小与它内容占据的大小范围相适应。
public class MyAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
//xml布局
//super.setUIContent(ResourceTable.Layout_ability_my);
// 1.声明布局
DependentLayout myLayout = new DependentLayout(this);
// 2.设置页面布局大小
myLayout.setWidth(MATCH_PARENT);
myLayout.setHeight(MATCH_PARENT);
//3.设置布局背景色
ShapeElement element = new ShapeElement();
element.setRgbColor(new RgbColor(255, 255, 255));
myLayout.setBackground(element);
// 4.1创建一个文本组件
Text text = new Text(this);
text.setText("My name is Text.");
text.setTextSize(55);
text.setTextColor(Color.BLACK);
// 4.2设置文本的布局
DependentLayout.LayoutConfig textConfig =
new DependentLayout.LayoutConfig(MATCH_CONTENT,MATCH_CONTENT);
textConfig.addRule(DependentLayout.LayoutConfig.CENTER_IN_PARENT);
text.setLayoutConfig(textConfig);
//5.将组件添加到布局中
myLayout.addComponent(text);
//6.将布局添加到组件树中
super.setUIContent(myLayout);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
启动测试
五、页面跳转
ability_main.xml
ability_main.xml是主页面布局xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_parent"
ohos:orientation="vertical"
ohos:padding="32">
<Text
ohos:id="$+id:text"
ohos:width="match_content"
ohos:height="match_content"
ohos:layout_alignment="horizontal_center"
ohos:text="这是第一张页面"
ohos:text_size="25vp"/>
<Button
ohos:id="$+id:button"
ohos:margin="50"
ohos:width="match_content"
ohos:height="match_content"
ohos:layout_alignment="horizontal_center"
ohos:background_element="$graphic:background_button"
ohos:text="跳转页面"
ohos:text_size="50"/>
</DirectionalLayout>
MyAbilitySlice
MyAbilitySlice是第二张页面,也是跳转页面.
public class MyAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
//xml布局
//super.setUIContent(ResourceTable.Layout_ability_my);
// 1.声明布局
DependentLayout myLayout = new DependentLayout(this);
// 2.设置页面布局大小
myLayout.setWidth(MATCH_PARENT);
myLayout.setHeight(MATCH_PARENT);
//3.设置布局背景色
ShapeElement element = new ShapeElement();
element.setRgbColor(new RgbColor(255, 255, 255));
myLayout.setBackground(element);
// 4.1创建一个文本组件
Text text = new Text(this);
text.setText("这是第二张页面");
text.setTextSize(55);
text.setTextColor(Color.BLACK);
// 4.2设置文本的布局
DependentLayout.LayoutConfig textConfig =
new DependentLayout.LayoutConfig(MATCH_CONTENT,MATCH_CONTENT);
textConfig.addRule(DependentLayout.LayoutConfig.CENTER_IN_PARENT);
text.setLayoutConfig(textConfig);
//5.将组件添加到布局中
myLayout.addComponent(text);
//6.将布局添加到组件树中
super.setUIContent(myLayout);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
MainAbilitySlice
MainAbilitySlice是主页面,跳转逻辑实现
public class MainAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
//获取xml布局里面的button
Button button = (Button) findComponentById(ResourceTable.Id_button);
if (button != null) {
// 为按钮设置监听事件
//方式一
// button.setClickedListener(component -> {
//
// });
//方式二
button.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
//跳转目的地
Intent secondIntent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")//方法跳转目的地的设备,"":本机
.withBundleName("com.example.myapplication")//跳转目标页面所在的应用
// .withAbilityName("com.example.myapplication.MyAbility")//跳转到应用的那个Ability上
.withAbilityName(".MyAbility")//跳转到应用的那个Ability上
.build();
secondIntent.setOperation(operation);
startAbility(secondIntent); // 通过AbilitySlice的startAbility接口实现从MainAbility跳转到MyAbility页面
}
});
}
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
启动测试
点击Button
点击”<“返回按钮
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/137080.html