学习更多:开发者文档中心-HarmonyOS NEXT/3.1/4.0开发文档-华为开发者联盟 (huawei.com)
一、概述
二、ArkUI组件
1、基础组件
(1)Image(图片显示组件)
声明Image组件并设置图片源:
Image(src: string|PixelMap|Resource)
- string格式,通常用来加载网络图片,需要在module.json5中配置申请网络访问权限:ohos.permission.INTERNET;
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
],
- PixelMap格式,可以加载像素图,常用在图片编辑中;
- Rescource格式,加载本地图片,可以通过$r或者$rawfile创建Resource对象;
Image($r('app.media.name')
Image($rawfile('filename'))
添加图片属性:
- width():宽度;
- height():高度;
- borderRadius():边框圆角;
- interpolation(ImageInterpolation.xxx):图片插值。
(2)Text(文本显示组件)
声明Text组件并设置文本内容:
Text(content?: string|Resource)
- string格式,直接填写文本内容;
- Rescoure格式,读取本地资源文件;
Text($r('app.string.name'))
添加文本属性:
- lineHeight():设置文本的文本行高,当值不大于0时,不限制文本行高,自适应字体大小;
- fontSize():字体大小;
- fontColor():字体颜色;
- fontWeight(FontWeight.xxx):字体粗细。
(3)TextInput(文本输入框)
声明TextInput组件:
TextInput({placeholder?: ResourceStr, text?: ResourceStr})
- placeholder:输入框无输入时的文本提示;
- text:输入框当前文本内容;
添加属性和事件:
- width():宽度;
- height():高度;
- backgroundColor():背景颜色;
- type(InputType.xxx):输入框类型,Normal基本输入模式,默认值,Password密码输入模式、Email邮箱地址输入模式、Number纯数字输入模式、PhoneNumber电话号码输入模式;
- onChange((value: string) => { }):内容发生变化时,触发该回调。
(4)Button(按钮组件)
声明Button组件,label是按钮文字:
Button(label?: ResourceStr)
- 文字型按钮:Button('Click');
- 自定义按钮,在Button内嵌套其他组件;
添加属性和事件:
- width():宽度;
- height():高度;
- type(IButtonType.xxx):按钮类型,Capsule:胶囊型按钮,默认值,Circle:圆形按钮,Normal:普通按钮(默认不带圆角);
- onClick(() => { }):处理点击事件。
(5)Slider(滑动条组件)
声明Slider组件:
Slider(option?: SliderOptions)
min | 最小值 | max | 最大值 |
value | 当前值 | step | 滑动步长 |
direction | 滑动条方向,Axis类型 | reverse | 是否反向滑动 |
style | 滑块和滑轨样式,SliderStyle类型,OutSet:滑块在滑轨上,InSet:滑块在滑轨内 |
添加属性和事件:
- width():宽度;
- showTips(boolean):显示百分比提示;
- blockColor():滑块颜色;
- trackThickness():滑动条粗细;
- onChange(value => { }):滑动时触发回调,value:滑动进度值。
2、容器组件
(1)线性布局(Row/Column)
对齐方式:
space | 子组件之间的距离 |
justifyContent | 子组件在主轴上的排列方式,实现布局自适应均分能力,取值FlexAlign类型 |
alignItems | 子组件在交叉轴上的排列方式,交叉轴为垂直方向取值VerticalAlign类型,水平方向取值HorizontalAlign类型 |
- justifyContent(FlexAlign.Start):子组件整体在主轴方向首端对齐;
- justifyContent(FlexAlign.Center):子组件整体在主轴方向居中对齐;
- justifyContent(FlexAlign.End):子组件整体在主轴方向尾部对齐;
- justifyContent(FlexAlign.Spacebetween):子组件在主轴方向两端对齐,相邻子组件之间距离相同;
- justifyContent(FlexAlign.SpaceAround):子组件在主轴方向排列,相邻子组件之间距离相同。第一个子组件到主轴开始位置和最后一个子组件到主轴结束位置的距离是相邻子组件之间距离的一半;
- justifyContent(FlexAlign.SpaceEvenly):子组件在主轴方向均匀分配,相邻元素之间的距离、第一个子组件到主轴开始位置、最后一个子组件到主轴结束位置的距离都一样。
练习:
@Entry @Component struct Index { @State imageWidth: number = 150 build() { Column() { Row(){ Image($r('app.media.img')) .width(this.imageWidth) .interpolation(ImageInterpolation.High) }.width('100%') .height(400) .justifyContent(FlexAlign.Center) Row(){ Text('图片宽度:') .fontSize(20) .fontWeight(FontWeight.Bolder) TextInput({ text: this.imageWidth.toFixed(0) }) // 数字转字符串 .width(200) .backgroundColor(Color.White) .type(InputType.Number) .fontSize(20) .onChange((value: string) => { this.imageWidth = parseInt(value) // 字符串转数字 }) }.width('100%') .justifyContent(FlexAlign.SpaceBetween) .padding({left: 20, right: 20}) Divider().width('90%') Row(){ Button('缩小') .width(80) .fontSize(20) .onClick(() => { if (this.imageWidth >= 10) { this.imageWidth -= 10 } }) Button('放大') .width(80) .fontSize(20) .onClick(() => { if (this.imageWidth < 300) { this.imageWidth += 10 } }) }.width('100%') .margin(30) .justifyContent(FlexAlign.SpaceEvenly) Slider({ min: 100, max: 300, value: this.imageWidth, step: 10 }) .width('100%') .blockColor('#36d') .trackThickness(10) .showTips(true) .onChange(value => { this.imageWidth = value }) } .width('100%') } }
(2)列表布局(List)
条件渲染:if-else
循环渲染:forEach()
ForEach(
// 必填项,要遍历的数组,允许设置为空数组,空数组场景下将不会创建子组件
arr: any[],// 必填项,生成子组件的lambda函数,为数组中的每一个数据项创建一个或多个子组件,单个子组件或子组件列表必须包括在大括号“{...}”中
itemGenerator: (item: any, index?: number) => void,// 可选项,匿名函数,用于给数组中的每一个数据项生成唯一且固定的键值
keyGenerator?: (item: any, index?: number) => string
)
列表特点:
- 列表是一种复杂的容器,当列表项(ListItem)达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能;
- 列表项(ListItem)既可以纵向排列,也可以横向排列,过listDirection属性设置;
- 列表布局通过List容器组件ListItemGroup或ListItem子组件实现。其中ListItemGroup用于列表数据的分组展示,其子组件也是ListItem,ListItem表示单个列表项;
练习:
class Item{ public name: string public img: Resource public price: number constructor(name, img, price) { this.name = name this.img = img this.price = price } } @Entry @Component struct Index { private items: Array<Item> = [ new Item('华为Mate60', $r('app.media.img'),6999), new Item('华为Mate60', $r('app.media.img'),6999), new Item('华为Mate60', $r('app.media.img'),6999), new Item('华为Mate60', $r('app.media.img'),6999), new Item('华为Mate60', $r('app.media.img'),6999), new Item('华为Mate60', $r('app.media.img'),6999), ] build() { Column({ space: 8 }){ Row(){ Text('商品列表') .fontSize(30) .fontWeight(FontWeight.Bold) }.width('100%') .margin({bottom: 20}) .height(30) List({ space: 8 }){ ForEach(this.items,(item: Item) => { ListItem(){ Row({ space: 10 }){ Image(item.img).width(100) Column({ space: 4 }){ Text(item.name).fontSize(20).fontWeight(FontWeight.Bold) Text('¥'+item.price).fontColor('#f36').fontSize(18) }.height('100%').alignItems(HorizontalAlign.Start) } .width('100%').backgroundColor(Color.White) .borderRadius(20).height(120).padding(10) } } ) }.width('100%') .layoutWeight(1) } } }
3、自定义组件
- 在当前文件中定义:@Component
- 在新的文件中定义:@Component,export,import
- 全局自定义构建函数:@Builder function
- 局部自定义构建函数:@Builder,无function关键字,调用时需使用this
- 全局自定义公共样式:@Styles function
- 局部自定义公共样式:@Styles,无function关键字
- 对于非公共样式:@Extend(组件) function,只能写为全局
小tips:可使用Blank()空白填充,将其后面的组件置于最末端。