组件(Component)是界面搭建与显示的最小单位,HarmonyOS ArkUI声明式开发范式为开发者提供了丰富多样的UI组件,我们可以使用这些组件轻松的编写出更加丰富、漂亮的界面
组件根据功能可以分为以下五大类:基础组件、容器组件、媒体组件、绘制组件、画布组件。其中基础组件是视图层的基本组成单元,包括Text、Image、TextInput、Button、LoadingProgress等
Text组件用于在界面上展示一段文本信息,可以包含子组件Span、针对包含文本元素的组件,例如Text、Span、Button、TextInput等,可使用fontColor、fontSize、fontStyle、 fontWeight、fontFamily这些文本样式,分别设置文本的颜色、大小、样式、粗细以及字体,文本样式的属性如下表所示:
名称 | 参数类型 | 描述 |
fontColor | ResourceColor | 设置文本颜色 |
fontSize | Length | Resource | 设置文本尺寸,Length为number类型时,使用fp单位 |
fontStyle | FontStyle | 设置文本的字体样式,默认值:FontStyle.Normal。 |
fontWeight | number | FontWeight | string | 描述见下文 |
fontFamily | string | Resource | 设置文本的字体列表。使用多个字体,使用“,”进行分割 |
fontWeight官网描述
设置文本的字体粗细,number类型取值[100, 900],取值间隔为100,默认为400,取值越大,字体越粗。string类型仅支持number类型取值的字符串形式,例如“400”,以及“bold”、“bolder”、“lighter”、“regular”、“medium”,分别对应FontWeight中相应的枚举值。默认值:FontWeight.Normal
textAlign参数类型为TextAlign,定义了以下三种类型:
- Start(默认值):水平对齐首部
- Center:水平居中对齐
- End:水平对齐尾部
Text('HarmonyOS')
.width(200)
.textAlign(TextAlign.Start)
.backgroundColor(0xE6F2FD)
当文本内容较多超出了Text组件范围的时候,可以使用textOverflow设置文本截取方式,需配合maxLines使用,maxLines用于设置文本显示最大行数
build() {
Column() {
Text('当文本内容较多超出了Text组件范围的时候,可以使用textOverflow设置文本截取方式,需配合maxLines使用,maxLines用于设置文本显示最大行数')
.fontSize(16)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.backgroundColor(0xE6F2FD)
}
}
使用decoration设置文本装饰线样式及其颜色,decoration包含type和color两个参数,其中type用于设置装饰线样式,参数类型为TextDecorationType,color为可选参数
- None:不使用文本装饰线
- Overline:文字上划线修饰
- LineThrough:删除线
- Underline:文字下划线修饰
Text('HarmonyOS')
.fontSize(20)
.decoration({ type: TextDecorationType.Underline, color: Color.Black })
.backgroundColor(0xE6F2FD)
TextInput组件用于输入单行文本,响应输入事件。TextInput的使用也非常广泛,例如应用登录账号密码、发送消息等,基本设置与Text一致
在TextInput中设置不同的输入类型有不同的呈现效果,如密码框,将type属性设置为InputType.Password就可以实现,
type的参数类型为InputType,包含以下几种输入类型:
- Normal:基本输入模式。支持输入数字、字母、下划线、空格、特殊字符
- Password:密码输入模式
- Email:e-mail地址输入模式
- Number:纯数字输入模式
TextInput({ placeholder: '请输入密码' })
.type(InputType.Password)
可以使用TextInputController动态设置光位置,使用TextInputController的caretPosition方法设置移动到第几个字符之后
TextInput({ controller: this.controller })
Button('设置光标位置')
.onClick(() => {
this.controller.caretPosition(2)
})
可以给TextInput设置onChange事件,输入文本发生变化时触发回调,下面示例代码中的value为实时获取用户输入的文本信息
TextInput({ placeholder: '请输入账号' })
.caretColor(Color.Blue)
// onChange事件
.onChange((value: string) => {
this.text = value
})
Text(this.text)
Image组件用来渲染展示图片,它可以让界面变得更加丰富多彩。只需要给Image组件设置图片地址、宽和高,图片就能加载出来
Image($r("app.media.icon"))
.width(100)
.height(100)
为了使图片在页面中有更好的显示效果,有时候需要对图片进行缩放处理。可以使用objectFit属性设置图片的缩放类型,objectFit的参数类型为ImageFit
- Cover(默认值):保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界
- Contain:保持宽高比进行缩小或者放大,使得图片完全显示在显示边界内
- Auto:自适应显示
- Fill:不保持宽高比进行放大缩小,使得图片充满显示边界
- ScaleDown:保持宽高比显示,图片缩小或者保持不变
- None:保持原有尺寸显示
Image组件支持加载网络图片,将图片地址换成网络图片地址进行加载,
注意:应用访问网络需要申请ohos.permission.INTERNET权限,因为HarmonyOS提供了一种访问控制机制即应用权限,用来保证这些数据或功能不会被不当或恶意使用
Image('https://www.xxx.com/xxx.png')
Button组件主要用来响应点击操作,可以包含子组件
Button('登录', { type: ButtonType.Capsule, stateEffect: true })
.width('90%')
.height(40)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.backgroundColor('#007DFF')
通过ButtonType可以设置按钮样式,按钮样式有以下三种样式
- Capsule:胶囊型按钮(圆角默认为高度的一半)
- Circle:圆形按钮
- Normal:普通按钮(默认不带圆角)
与TextInput设置onChange回调一样,Button设置的是onClick事件,每当用户点击Button的时候,就会回调执行onClick方法
Button('登录', { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 处理点击事件逻辑
})
Button组件可以包含子组件,可以开发出更丰富多样的Button,下面的示例是包含图标的按钮
Button({ type: ButtonType.Circle, stateEffect: true }) {
Image($r('app.media.icon'))
.width(30)
.height(30)
}
.width(55)
.height(55)
.backgroundColor(0x317aff)
LoadingProgress组件用于显示加载进展,比如应用的登录界面,当我们点击登录的时候,显示的“正在登录”的进度条状态。
LoadingProgress的使用非常简单,只需要设置颜色和宽高就可以了
LoadingProgress()
.color(Color.Blue)
.height(60)
.width(60)
Resource是资源引用类型,用于设置组件属性的值。推荐大家优先使用Resource类型,将资源文件(字符串、图片、音频等)统一存放于resources目录下,便于开发者统一维护
在Button组件通过“$r('app.type.name')”的形式引用应用资源。app代表应用内resources目录中定义的资源;type代表资源类型(或资源的存放位置),可以取“color”、“float”、“string”、“plural”、“media”;name代表资源命名,由开发者定义资源时确定
{
"string": [
{
"name": "login_text",
"value": "登录"
}
]
}
{
"float": [
{
"name": "button_width",
"value": "300vp"
},
{
"name": "button_height",
"value": "40vp"
},
{
"name": "login_fontSize",
"value": "18fp"
}
]
}
{
"color": [
{
"name": "button_color",
"value": "#1890ff"
}
]
}
容器组件是一种比较特殊的组件,它可以包含其他的组件,而且按照一定的规律布局,帮助开发者生成精美的页面
- Column是垂直方向的容器组件
- Row是水平方向的容器组件
每个容器都有一条主轴和交叉轴,这里熟悉flex布局的就相对简单啦,类似的原理,建议先看下flex布局,两条轴以官网的示例图展示
Column垂直方向为主轴,Row水平方向为主轴
这块官网描述比较晦涩,简单一句话就是一个两个方向(垂直和水平),与主轴相对方向的就是交叉轴
类似于flex布局,主要是几种对齐方式(子组件在主轴和交叉轴的排列方式)
属性名称 | 描述 |
justifyContent | 设置子组件在主轴方向上的对齐格式 |
alignItems | 设置子组件在交叉轴方向上的对齐格式 |
justifyContent的类型是FlexAlign,FlexAlign定义了6种布局方式
- Start:元素在主轴方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐
- Center:元素在主轴方向中心对齐,第一个元素与行首的距离以及最后一个元素与行尾距离相同
- End:元素在主轴方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐
- SpaceBetween:元素在主轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素与行首对齐,最后一个元素与行尾对齐
- SpaceAround:元素在主轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半
- SpaceEvenly:元素在主轴方向等间距布局,无论是相邻元素还是边界元素到容器的间距都一样
具体截图不再一一展示,可以参考官网链接,一看就懂传送门
类似于flex布局,子组件在交叉轴方向上的对齐方式使用alignItems属性来设置,这里分容器对应不同设置
Column容器的主轴是垂直方向,交叉轴是水平方向,其参数类型为HorizontalAlign(水平对齐),HorizontalAlign定义了以下三种类型
- Start:设置子组件在水平方向上按照起始端对齐
- Center(默认值):设置子组件在水平方向上居中对齐
- End:设置子组件在水平方向上按照末端对齐
Row容器的主轴是水平方向,交叉轴是垂直方向,其参数类型为VerticalAlign(垂直对齐),VerticalAlign定义了以下三种类型
- Top:设置子组件在垂直方向上居顶部对齐
- Center(默认值):设置子组件在竖直方向上居中对齐
- Bottom:设置子组件在竖直方向上居底部对齐
Column和Row容器的接口,Column和Row容器的接口都有一个可选参数space,表示子组件在主轴方向上的间距
容器组件 | 接口 |
Column | Column(value?:{space?: string | number}) |
Row | Row(value?:{space?: string | number}) |
List是很常用的滚动类容器组件,一般和子组件ListItem一起使用,List列表中的每一个列表项对应一个ListItem组件
列表往往由多个列表项组成,所以我们需要在List组件中使用多个ListItem组件来构建列表,这就会导致代码的冗余。使用循环渲染(ForEach)遍历数组的方式构建列表
@Entry
@Component
struct ListDemo {
private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
build() {
Column() {
List({ space: 10 }) {
ForEach(this.arr, (item: number) => {
ListItem() {
Text(`${item}`)
.width('100%')
.height(100)
.fontSize(20)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.borderRadius(10)
.backgroundColor(0x007DFF)
}
}, item => item)
}
}
.padding(12)
.height('100%')
.backgroundColor(0xF1F3F5)
}
}
List组件子组件ListItem之间默认是没有分割线的,需要设置分割线,这时候可以使用List组件的divider属性,divider属性包含四个参数
- strokeWidth: 分割线的线宽
- color: 分割线的颜色
- startMargin:分割线距离列表侧边起始端的距离
- endMargin: 分割线距离列表侧边结束端的距离
ist组件提供了一系列事件方法用来监听列表的滚动,可以根据需要,监听这些事件来做一些操作
- onScroll:列表滑动时触发,返回值scrollOffset为滑动偏移量,scrollState为当前滑动状态
- onScrollIndex:列表滑动时触发,返回值分别为滑动起始位置索引值与滑动结束位置索引值
- onReachStart:列表到达起始位置时触发
- onReachEnd:列表到底末尾位置时触发
- onScrollStop:列表滑动停止时触发
List({ space: 10 }) {
ForEach(this.arr, (item) => {
ListItem() {
Text(`${item}`)
...
}
}, item => item)
}
.onScrollIndex((firstIndex: number, lastIndex: number) => {
console.info('first' + firstIndex)
console.info('last' + lastIndex)
})
.onScroll((scrollOffset: number, scrollState: ScrollState) => {
console.info('scrollOffset' + scrollOffset)
console.info('scrollState' + scrollState)
})
.onReachStart(() => {
console.info('onReachStart')
})
.onReachEnd(() => {
console.info('onReachEnd')
})
.onScrollStop(() => {
console.info('onScrollStop')
})
List组件里面的列表项默认是按垂直方向排列的,如果您想让列表沿水平方向排列,您可以将List组件的listDirection属性设置为Axis.Horizontal,Axis提供两种类型
- Vertical(默认值):子组件ListItem在List容器组件中呈纵向排列
- Horizontal:子组件ListItem在List容器组件中呈横向排列
Grid组件为网格容器,是一种网格列表,由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。Grid组件一般和子组件GridItem一起使用,Grid列表中的每一个条目对应一个GridItem组件
和List组件一样,Grid组件也可以使用ForEach来渲染多个列表项GridItem,我们通过下面的这段示例代码来介绍Grid组件的使用
@Entry
@Component
struct GridExample {
// 定义一个长度为16的数组
private arr: string[] = new Array(16).fill('').map((_, index) => `item ${index}`);
build() {
Column() {
Grid() {
ForEach(this.arr, (item: string) => {
GridItem() {
Text(item)
.fontSize(16)
.fontColor(Color.White)
.backgroundColor(0x007DFF)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
}, item => item)
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.height(300)
}
.width('100%')
.padding(12)
.backgroundColor(0xF1F3F5)
}
}
columnsTemplate的值为'1fr 1fr 1fr 1fr',表示这个网格为4列,将Grid允许的宽分为4等分,每列占1份;
rowsTemplate的值为'1fr 1fr 1fr 1fr',表示这个网格为4行,将Grid允许的高分为4等分,每行占1份。
然后使用columnsGap设置列间距为10vp,使用rowsGap设置行间距也为10vp。
ArkUI开发框架提供了一种页签容器组件Tabs,开发者通过Tabs组件可以很容易的实现内容视图的切换。页签容器Tabs的形式多种多样,不同的页面设计页签不一样,可以把页签设置在底部、顶部或者侧边,官网演示效果图如下
Tabs组件仅可包含子组件TabContent,每一个页签对应一个内容视图即TabContent组件
@Entry
@Component
struct TabsExample {
private controller: TabsController = new TabsController()
build() {
Column() {
Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {
TabContent() {
Column().width('100%').height('100%').backgroundColor(Color.Green)
}
.tabBar('green')
TabContent() {
Column().width('100%').height('100%').backgroundColor(Color.Blue)
}
.tabBar('blue')
}
.barWidth('100%') // 设置TabBar宽度
.barHeight(60) // 设置TabBar高度
.width('100%') // 设置Tabs组件宽度
.height('100%') // 设置Tabs组件高度
.backgroundColor(0xF5F5F5) // 设置Tabs组件背景颜色
}
.width('100%')
.height('100%')
}
}
因为Tabs的布局模式默认是Fixed的,所以Tabs的页签是不可滑动的。当页签比较多的时候,可能会导致页签显示不全,将布局模式设置为Scrollable的话,可以实现页签的滚动
Tabs的布局模式有Fixed(默认)和Scrollable两种
- BarMode.Fixed:所有TabBar平均分配barWidth宽度(纵向时平均分配barHeight高度),页签不可滚动
- BarMode.Scrollable:每一个TabBar均使用实际布局宽度,超过总长度(横向Tabs的barWidth,纵向Tabs的barHeight)后可滑动
可以使用Tabs组件接口中的参数barPosition设置页签位置。此外页签显示位置还与vertical属性相关联,vertical属性用于设置页签的排列方向,当vertical的属性值为false(默认值)时页签横向排列,为true时页签纵向排列
barPosition的值可以设置为BarPosition.Start(默认值)和BarPosition.End
- BarPosition.Start: vertical属性方法设置为false(默认值)时,页签位于容器顶部
- BarPosition.End:vertical属性方法设置为false时,页签位于容器底部
Gitee地址:https://gitee.com/harmonyos/codelabs/tree/master/ArkTSComponents
静待补充 很快 大家圣诞快乐!!!