鸿蒙开发之UI框架

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 鸿蒙开发之UI框架,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、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

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!