HarmonyOS常用基础组件
文章目录
- 一、基础组件
- 1. Text
- 2. Image
- 3. TextInput
- 4. Button
- 5. LoadingProgress
- 二、容器组件
- 1. 布局容器概念
- 2. 主轴和交叉轴概念
- 3. 主轴方向的对齐(justifyContent)
- 4. 交叉轴方向的对齐(alignItems)
- 5. 代码示例
- 三、列表页面
- 1. List组件
- 2. Grid组件
- 四、页签Tabs
- 1. TabContent
- 2. 设置TabBar布局模式
- 3. 设置TabBar位置和排列方向
- 4. 自定义TabBar样式
一、基础组件
组件(Component)是界面搭建与显示的最小单位。
组件根据功能可以分为以下五大类:基础组件、容器组件、媒体组件、绘制组件、画布组件。其中基础组件是视图层的基本组成单元,包括Text、Image、TextInput、Button、LoadingProgress等。
1. Text
Text组件用于在界面上展示一段文本信息,可以包含子组件Span。
文本样式
名称 | 参数类型 | 描述 |
---|---|---|
fontColor | ResourceColor | 设置文本颜色。 |
fontSize | Length | Resource | 设置文本尺寸,Length为number类型时,使用fp单位。 |
fontStyle | FontStyle | 设置文本的字体样式。默认值:FontStyle.Normal。 |
fontWeight | number | FontWeight | string | 设置文本的字体粗细,number类型取值[100, 900],取值间隔为100,默认为400,取值越大,字体越粗。string类型仅支持number类型取值的字符串形式,例如“400”,以及“bold”、“bolder”、“lighter”、“regular”、“medium”,分别对应FontWeight中相应的枚举值。默认值:FontWeight.Normal。 |
fontFamily | string | Resource | 设置文本的字体列表。使用多个字体,使用“,”进行分割,优先级按顺序生效。例如:“Arial,sans-serif”。 |
设置文本对齐方式
Text('HarmonyOS')
.width(200)
.textAlign(TextAlign.Start)
.backgroundColor(0xE6F2FD)
textAlign参数类型为TextAlign,
- Start(默认值):水平对齐首部。
- Center:水平居中对齐。
- End:水平对齐尾部。
设置文本超长显示
当文本内容较多超出了Text组件范围的时候,您可以使用textOverflow设置文本截取方式,需配合maxLines使用,单独设置不生效,maxLines用于设置文本显示最大行数。
Text('This is the text content of Text Component This is the text content of Text Component')
.fontSize(16)
.maxLines(1)
.textOverflow({overflow:TextOverflow.Ellipsis})
.backgroundColor(0xE6F2FD)
设置文本装饰线
使用decoration设置文本装饰线样式及其颜色.decoration包含type和color两个参数,其中type用于设置装饰线样式,参数类型为TextDecorationType,color为可选参数。
Text('HarmonyOS')
.fontSize(20)
.decoration({ type: TextDecorationType.Underline, color: Color.Black })
.backgroundColor(0xE6F2FD)
- None:不使用文本装饰线。
- Overline:文字上划线修饰。
- LineThrough:穿过文本的修饰线。
- Underline:文字下划线修饰。
2. Image
Image($r("app.media.icon"))
.width(100)
.height(100)
设置缩放类型
使用objectFit属性设置图片的缩放类型,objectFit的参数类型为ImageFit。
Image($r("app.media.image2"))
.objectFit(ImageFit.Cover)
.backgroundColor(0xCCCCCC)
.width(100)
.height(100)
- Contain:保持宽高比进行缩小或者放大,使得图片完全显示在显示边界内。
- Cover(默认值):保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界。
- Auto:自适应显示。
- Fill:不保持宽高比进行放大缩小,使得图片充满显示边界。
- ScaleDown:保持宽高比显示,图片缩小或者保持不变。
- None:保持原有尺寸显示。
加载网络图片
Image('https://www.example.com/xxx.png')
为了成功加载网络图片,您需要在module.json5文件中申明网络访问权限。
{
"module" : {
"requestPermissions":[
{
"name": "ohos.permission.INTERNET"
}
]
}
}
3. TextInput
TextInput组件用于输入单行文本,响应输入事件。
TextInput()
.fontColor(Color.Blue)
.fontSize(20)
.fontStyle(FontStyle.Italic)
.fontWeight(FontWeight.Bold)
.fontFamily('Arial')
设置输入提示文本
TextInput({ placeholder: '请输入帐号' })
.placeholderColor(0x999999)
.placeholderFont({ size: 20, weight: FontWeight.Medium, family: 'cursive', style: FontStyle.Italic })
设置输入类型
可以使用type属性来设置输入框类型。type的参数类型为InputType
TextInput({ placeholder: '请输入密码' })
.type(InputType.Password)
- Normal:基本输入模式。支持输入数字、字母、下划线、空格、特殊字符。
- Password:密码输入模式。
- Email:e-mail地址输入模式。
- Number:纯数字输入模式。
设置光标位置
可以使用TextInputController动态设置光位置
@Entry
@Component
struct TextInputDemo {
controller: TextInputController = new TextInputController()
build() {
Column() {
TextInput({ controller: this.controller })
Button('设置光标位置')
.onClick(() => {
this.controller.caretPosition(2)
})
}
.height('100%')
.backgroundColor(0xE6F2FD)
}
}
获取输入文本
@Entry
@Component
struct TextInputDemo {
@State text: string = ''
build() {
Column() {
TextInput({ placeholder: '请输入账号' })
.caretColor(Color.Blue)
.onChange((value: string) => {
this.text = value
})
Text(this.text)
}
.alignItems(HorizontalAlign.Center)
.padding(12)
.backgroundColor(0xE6F2FD)
}
}
4. Button
Button组件主要用来响应点击操作,可以包含子组件。
Button('登录', { type: ButtonType.Capsule, stateEffect: true })
.width('90%')
.height(40)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.backgroundColor('#007DFF')
设置按钮样式
type用于定义按钮样式,
- Capsule:胶囊型按钮(圆角默认为高度的一半)。
- Circle:圆形按钮。
- Normal:普通按钮(默认不带圆角)。
设置按钮点击事件
Button('登录', { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 处理点击事件逻辑
})
包含子组件
Button({ type: ButtonType.Circle, stateEffect: true }) {
Image($r('app.media.icon_delete'))
.width(30)
.height(30)
}
.width(55)
.height(55)
.backgroundColor(0x317aff)
5. LoadingProgress
LoadingProgress组件用于显示加载进展
LoadingProgress()
.color(Color.Blue)
.height(60)
.width(60)
二、容器组件
1. 布局容器概念
- Column表示沿垂直方向布局的容器。
- Row表示沿水平方向布局的容器。
2. 主轴和交叉轴概念
- 主轴:在Column容器中的子组件是按照从上到下的垂直方向布局的,其主轴的方向是垂直方向;在Row容器中的组件是按照从左到右的水平方向布局的,其主轴的方向是水平方向。
- 交叉轴:与主轴垂直相交的轴线,如果主轴是垂直方向,则交叉轴就是水平方向;如果主轴是水平方向,则交叉轴是垂直方向。
3. 主轴方向的对齐(justifyContent)
参数类型是FlexAlign
- Start:元素在主轴方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐。
- Center:元素在主轴方向中心对齐,第一个元素与行首的距离以及最后一个元素与行尾距离相同。
- End:元素在主轴方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐。
- SpaceBetween:元素在主轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素与行首对齐,最后一个元素与行尾对齐。
- SpaceAround:元素在主轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半。
- SpaceEvenly:元素在主轴方向等间距布局,无论是相邻元素还是边界元素到容器的间距都一样。
4. 交叉轴方向的对齐(alignItems)
Column容器的主轴是垂直方向,交叉轴是水平方向,其参数类型为HorizontalAlign(水平对齐)
- Start:设置子组件在水平方向上按照起始端对齐。
- Center(默认值):设置子组件在水平方向上居中对齐。
- End:设置子组件在水平方向上按照末端对齐。
Row容器的主轴是水平方向,交叉轴是垂直方向,其参数类型为VerticalAlign(垂直对齐)
- Top:设置子组件在垂直方向上居顶部对齐。
- Center(默认值):设置子组件在竖直方向上居中对齐。
- Bottom:设置子组件在竖直方向上居底部对齐。
5. 代码示例
@Entry
@Component
export struct LoginPage {
build() {
Column() {
Image($r('app.media.logo'))
...
Text($r('app.string.login_page'))
...
Text($r('app.string.login_more'))
...
TextInput({ placeholder: $r('app.string.account') })
...
TextInput({ placeholder: $r('app.string.password') })
...
Row() {
Text($r(…))
Text($r(…))
}
Button($r('app.string.login'), { type: ButtonType.Capsule, stateEffect: true })
...
Row() {
this.imageButton($r(…))
this.imageButton($r(…))
this.imageButton($r(…))
}
...
}
...
}
}
三、列表页面
1. List组件
List组件简介
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)
}
}
设置列表分割线
使用 divider属性,包含四个参数:
- strokeWidth: 分割线的线宽。
- color: 分割线的颜色。
- startMargin:分割线距离列表侧边起始端的距离。
- endMargin: 分割线距离列表侧边结束端的距离。
List列表滚动事件监听
- 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排列方向
listDirection参数类型是Axis
- Vertical(默认值):子组件ListItem在List容器组件中呈纵向排列。
- Horizontal:子组件ListItem在List容器组件中呈横向排列。
2. Grid组件
Grid组件简介
Grid组件为网格容器,是一种网格列表,由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。Grid组件一般和子组件GridItem一起使用,Grid列表中的每一个条目对应一个GridItem组件。
使用ForEach渲染网格布局
@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)
}
}
四、页签Tabs
页签容器Tabs的形式多种多样,不同的页面设计页签不一样,可以把页签设置在底部、顶部或者侧边。
1. 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')
TabContent() {
Column().width('100%').height('100%').backgroundColor(Color.Yellow)
}
.tabBar('yellow')
TabContent() {
Column().width('100%').height('100%').backgroundColor(Color.Pink)
}
.tabBar('pink')
}
.barWidth('100%') // 设置TabBar宽度
.barHeight(60) // 设置TabBar高度
.width('100%') // 设置Tabs组件宽度
.height('100%') // 设置Tabs组件高度
.backgroundColor(0xF5F5F5) // 设置Tabs组件背景颜色
}
.width('100%')
.height('100%')
}
}
2. 设置TabBar布局模式
因为Tabs的布局模式默认是Fixed的,所以Tabs的页签是不可滑动的。当页签比较多的时候,可能会导致页签显示不全,将布局模式设置为Scrollable的话,可以实现页签的滚动。
- BarMode.Fixed:所有TabBar平均分配barWidth宽度(纵向时平均分配barHeight高度),页签不可滚动,效果图如下:
- BarMode.Scrollable:每一个TabBar均使用实际布局宽度,超过总长度(横向Tabs的barWidth,纵向Tabs的barHeight)后可滑动。
@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')
...
}
.barMode(BarMode.Scrollable)
.barWidth('100%')
.barHeight(60)
.width('100%')
.height('100%')
}
}
}
3. 设置TabBar位置和排列方向
可以使用Tabs组件接口中的参数barPosition设置页签位置。
- BarPosition.Start
vertical属性方法设置为false(默认值)时,页签位于容器顶部。
vertical属性方法设置为true时,页签位于容器左侧。
Tabs({ barPosition: BarPosition.Start }) {
...
}
.vertical(false)
.barWidth('100%')
.barHeight(60)
- BarPosition.End
vertical属性方法设置为false时,页签位于容器底部。
vertical属性方法设置为true时,页签位于容器右侧。
Tabs({ barPosition: BarPosition.End}) {
...
}
.vertical(true)
.barWidth(100)
.barHeight(200)
4. 自定义TabBar样式
TabContent的tabBar属性除了支持string类型,还支持使用@Builder装饰器修饰的函数。
@Entry
@Component
struct TabsExample {
@State currentIndex: number = 0;
private tabsController: TabsController = new TabsController();
@Builder TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {
Column() {
Image(this.currentIndex === targetIndex ? selectedImg : normalImg)
.size({ width: 25, height: 25 })
Text(title)
.fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B')
}
.width('100%')
.height(50)
.justifyContent(FlexAlign.Center)
.onClick(() => {
this.currentIndex = targetIndex;
this.tabsController.changeIndex(this.currentIndex);
})
}
build() {
Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
TabContent() {
Column().width('100%').height('100%').backgroundColor('#00CB87')
}
.tabBar(this.TabBuilder('首页', 0, $r('app.media.home_selected'), $r('app.media.home_normal')))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#007DFF')
}
.tabBar(this.TabBuilder('我的', 1, $r('app.media.mine_selected'), $r('app.media.mine_normal')))
}
.barWidth('100%')
.barHeight(50)
.onChange((index: number) => {
this.currentIndex = index;
})
}
}
使用@Builder修饰TabBuilder函数,生成由Image和Text组成的页签。同时也给Tabs组件设置了TabsController控制器,当点击某个页签时,调用changeIndex方法进行页签内容切换。