ArkUI进阶-1
文章目录
(今天更新的内容是轮播图与文本输入)
ArkUI(方舟UI框架)
1.简介
ArkUI(方舟UI框架)为应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能(组件、布局、动画以及交互事件),以及实时界面预览工具等,可以支持开发者进行可视化界面开发。
2.基本概念
- UI: 即用户界面。开发者可以将应用的用户界面设计为多个功能页面,每个页面进行单独的文件管理,并通过页面路由API完成页面间的调度管理如跳转、回退等操作,以实现应用内的功能解耦。
- 组件: UI构建与显示的最小单位,如列表、网格、按钮、单选框、进度条、文本等。开发者通过多种组件的组合,构建出满足自身应用诉求的完整界面。
3.概述
(将根据概述的点进行总结)
-
ArkTS
ArkTS是优选的主力应用开发语言,围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展。扩展能力包含声明式UI描述、自定义组件、动态扩展UI元素、状态管理和渲染控制。状态管理作为基于ArkTS的声明式开发范式的特色,通过功能不同的装饰器给开发者提供了清晰的页面更新渲染流程和管道。状态管理包括UI组件状态和应用程序状态,两者协作可以使开发者完整地构建整个应用的数据更新和UI渲染。ArkTS语言的基础知识请参考初识ArkTS语言。
-
布局
布局是UI的必要元素,它定义了组件在界面中的位置。ArkUI框架提供了多种布局方式,除了基础的线性布局、层叠布局、弹性布局、相对布局、栅格布局外,也提供了相对复杂的列表、宫格、轮播。
-
组件
组件是UI的必要元素,形成了在界面中的样子,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。系统内置组件包括按钮、单选框、进度条、文本等。开发者可以通过链式调用的方式设置系统内置组件的渲染效果。开发者可以将系统内置组件组合为自定义组件,通过这种方式将页面组件化为一个个独立的UI单元,实现页面不同单元的独立创建、开发和复用,具有更强的工程性。
-
页面路由和组件导航
应用可能包含多个页面,可通过页面路由实现页面间的跳转。一个页面内可能存在组件间的导航如典型的分栏,可通过导航组件实现组件间的导航。
-
图形
方舟开发框架提供了多种类型图片的显示能力和多种自定义绘制的能力,以满足开发者的自定义绘图需求,支持绘制形状、填充颜色、绘制文本、变形与裁剪、嵌入图片等。
-
动画
动画是UI的重要元素之一。优秀的动画设计能够极大地提升用户体验,框架提供了丰富的动画能力,除了组件内置动画效果外,还包括属性动画、显式动画、自定义转场动画以及动画API等,开发者可以通过封装的物理模型或者调用动画能力API来实现自定义动画轨迹。
-
交互事件
交互事件是UI和用户交互的必要元素。方舟开发框架提供了多种交互事件,除了触摸事件、鼠标事件、键盘按键事件、焦点事件等通用事件外,还包括基于通用事件进行进一步识别的手势事件。手势事件有单一手势如点击手势、长按手势、拖动手势、捏合手势、旋转手势、滑动手势,以及通过单一手势事件进行组合的组合手势事件。
-
自定义能力
自定义能力是UI开发框架提供给开发者对UI界面进行开发和定制化的能力。包括:自定义组合、自定义扩展、自定义节点和自定义渲染。
4.布局
1.概述
(与前端的基本布局差不多,有前端基础的小伙伴很好上手的)
布局通常为分层结构,一个常见的页面结构如下所示:
为实现上述效果,开发者需要在页面中声明对应的元素。其中,Page表示页面的根节点,Column/Row等元素为系统组件。针对不同的页面结构,ArkUI提供了不同的布局组件来帮助开发者实现对应布局的效果,例如Row用于实现线性布局。
2.布局元素的组成
布局相关的容器组件可形成对应的布局效果。例如,List组件可构成线性布局。
布局元素组成图
- 组件区域(蓝区方块):组件区域表示组件的大小,width、height属性用于设置组件区域的大小。
- 组件内容区(黄色方块):组件内容区大小为组件区域大小减去组件的border值,组件内容区大小会作为组件内容(或者子组件)进行大小测算时的布局测算限制。
- 组件内容(绿色方块):组件内容本身占用的大小,比如文本内容占用的大小。组件内容和组件内容区不一定匹配,比如设置了固定的width和height,此时组件内容的大小就是设置的width和height减去padding和border值,但文本内容则是通过文本布局引擎测算后得到的大小,可能出现文本真实大小小于设置的组件内容区大小。当组件内容和组件内容区大小不一致时,align属性生效,定义组件内容在组件内容区的对齐方式,如居中对齐。
- 组件布局边界(虚线部分):组件通过margin属性设置外边距时,组件布局边界就是组件区域加上margin的大小。
3.所有布局样式
布局 | 应用场景 |
---|---|
线性布局(Row、Column) | 如果布局内子元素超过1个时,且能够以某种方式线性排列时优先考虑此布局。 |
层叠布局(Stack) | 组件需要有堆叠效果时优先考虑此布局。层叠布局的堆叠效果不会占用或影响其他同容器内子组件的布局空间。例如Panel作为子组件弹出时将其他组件覆盖更为合理,则优先考虑在外层使用堆叠布局。 |
弹性布局(Flex) | 弹性布局是与线性布局类似的布局方式。区别在于弹性布局默认能够使子组件压缩或拉伸。在子组件需要计算拉伸或压缩比例时优先使用此布局,可使得多个容器内子组件能有更好的视觉上的填充效果。 |
相对布局(RelativeContainer) | 相对布局是在二维空间中的布局方式,不需要遵循线性布局的规则,布局方式更为自由。通过在子组件上设置锚点规则(AlignRules)使子组件能够将自己在横轴、纵轴中的位置与容器或容器内其他子组件的位置对齐。设置的锚点规则可以天然支持子元素压缩、拉伸、堆叠或形成多行效果。在页面元素分布复杂或通过线性布局会使容器嵌套层数过深时推荐使用。 |
栅格布局(GridRow、GridCol) | 栅格是多设备场景下通用的辅助定位工具,可将空间分割为有规律的栅格。栅格不同于网格布局固定的空间划分,可以实现不同设备下不同的布局,空间划分更随心所欲,从而显著降低适配不同屏幕尺寸的设计及开发成本,使得整体设计和开发流程更有秩序和节奏感,同时也保证多设备上应用显示的协调性和一致性,提升用户体验。推荐内容相同但布局不同时使用。 |
媒体查询(@ohos.mediaquery) | 媒体查询可根据不同设备类型或同设备不同状态修改应用的样式。例如根据设备和应用的不同属性信息设计不同的布局,以及屏幕发生动态改变时更新应用的页面布局。 |
列表(List) | 使用列表可以高效地显示结构化、可滚动的信息。在ArkUI中,列表具有垂直和水平布局能力和自适应交叉轴方向上排列个数的布局能力,超出屏幕时可以滚动。列表适合用于呈现同类数据类型或数据类型集,例如图片和文本。 |
网格(Grid) | 网格布局具有较强的页面均分能力、子元素占比控制能力。网格布局可以控制元素所占的网格数量、设置子元素横跨几行或者几列,当网格容器尺寸发生变化时,所有子元素以及间距等比例调整。推荐在需要按照固定比例或者均匀分配空间的布局场景下使用,例如计算器、相册、日历等。 |
轮播(Swiper) | 轮播组件通常用于实现广告轮播、图片预览等。 |
选项卡(Tabs) | 选项卡可以在一个页面内快速实现视图内容的切换,一方面提升查找信息的效率,另一方面精简用户单次获取到的信息量。 |
3.对子元素的约束
约束 | 使用场景 | 实现方式 |
---|---|---|
拉伸 | 容器组件尺寸发生变化时,增加或减小的空间全部分配给容器组件内指定区域。 | flexGrow和flexShrink属性:1. flexGrow基于父容器的剩余空间分配来控制组件拉伸。2. flexShrink设置父容器的压缩尺寸来控制组件压缩。 |
缩放 | 子组件的宽高按照预设的比例,随容器组件发生变化,且变化过程中子组件的宽高比不变。 | aspectRatio属性指定当前组件的宽高比来控制缩放,公式为:aspectRatio=width/height。 |
占比 | 占比能力是指子组件的宽高按照预设的比例,随父容器组件发生变化。 | 基于通用属性的两种实现方式:1. 将子组件的宽高设置为父组件宽高的百分比。2. layoutWeight属性,使得子元素自适应占满剩余空间。 |
隐藏 | 隐藏能力是指容器组件内的子组件,按照其预设的显示优先级,随容器组件尺寸变化显示或隐藏,其中相同显示优先级的子组件同时显示或隐藏。 | 通过displayPriority属性来控制组件的显示和隐藏。 |
2.通用布局属性
1.盒子属性
1.常用的属性
属性 | 描述 |
---|---|
padding | 内边距 |
margin | 外边距 |
border | 边框线 |
borderRadius | 边框圆角 |
2.内边距 padding
属性:数字 或 对象{}
-
数字:上下左右内边距相同
-
对象{}:配合 left、right、top、bottom 单独设置某个方向内边距
@Entry @Component struct Index {build() {Column() {Text('文字').backgroundColor(Color.Pink)// 单值:四个方向padding相同.padding(20)// 对象:单独设置某个方向.padding({top: 10,right: 20,bottom: 40,left: 80})}} }
4.边框属性
属性:
border()
参数:
{width?: 数字, color?: '', style?: BorderStyle}
,- width:边框宽度,边框宽度默认值为0,即不显示边框
- color:边框颜色
- style:边框样式,
BorderStyle
为枚举类型 -
- Solid:实线(默认)
- Dashed:虚线
- Dotted:点线
5.边框圆角
属性:borderRadius(圆角半径)
参数:数值 或 { }
- topLeft:左上角
- topRight:右上角
- bottomLeft:左下角
- bottomRight:右下角
// xxx.ets
@Entry
@Component
struct BorderExample {build() {Column() {Flex({ justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {// 线段Text('dashed').borderStyle(BorderStyle.Dashed).borderWidth(5).borderColor(0xAFEEEE).borderRadius(10).width(120).height(120).textAlign(TextAlign.Center).fontSize(16)// 点线Text('dotted').border({ width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Dotted }).width(120).height(120).textAlign(TextAlign.Center).fontSize(16)}.width('100%').height(150)Text('.border').fontSize(50).width(300).height(300).border({width: { left: 3, right: 6, top: 10, bottom: 15 },color: { left: '#e3bbbb', right: Color.Blue, top: Color.Red, bottom: Color.Green },radius: { topLeft: 10, topRight: 20, bottomLeft: 40, bottomRight: 80 },style: {left: BorderStyle.Dotted,right: BorderStyle.Dotted,top: BorderStyle.Solid,bottom: BorderStyle.Dashed}}).textAlign(TextAlign.Center)}}
}
2.背景属性
1.背景图片
属性 | 描述 |
---|---|
backgroundColor | 背景色 |
backgroundImage | 背景图 |
backgroundImageSize | 背景图尺寸 |
backgroundImagePosition | 背景图位置 |
// xxx.ets
@Entry
@Component
struct BackgroundExample {build() {Column({ space: 5 }) {Text('background color').fontSize(9).width('90%').fontColor(0xCCCCCC)Row().width('90%').height(50).backgroundColor(0xE5E5E5).border({ width: 1 })Text('background image repeat along X').fontSize(9).width('90%').fontColor(0xCCCCCC)Row().backgroundImage('/comment/bg.jpg', ImageRepeat.X).backgroundImageSize({ width: '250px', height: '140px' }).width('90%').height(70).border({ width: 1 })Text('background image repeat along Y').fontSize(9).width('90%').fontColor(0xCCCCCC)Row().backgroundImage('/comment/bg.jpg', ImageRepeat.Y).backgroundImageSize({ width: '500px', height: '120px' }).width('90%').height(100).border({ width: 1 })Text('background image size').fontSize(9).width('90%').fontColor(0xCCCCCC)Row().width('90%').height(150).backgroundImage('/comment/bg.jpg', ImageRepeat.NoRepeat).backgroundImageSize({ width: 1000, height: 500 }).border({ width: 1 })Text('background fill the box(Cover)').fontSize(9).width('90%').fontColor(0xCCCCCC)// 不保证图片完整的情况下占满盒子Row().width(200).height(50).backgroundImage('/comment/bg.jpg', ImageRepeat.NoRepeat).backgroundImageSize(ImageSize.Cover).border({ width: 1 })Text('background fill the box(Contain)').fontSize(9).width('90%').fontColor(0xCCCCCC)// 保证图片完整的情况下放到最大Row().width(200).height(50).backgroundImage('/comment/bg.jpg', ImageRepeat.NoRepeat).backgroundImageSize(ImageSize.Contain).border({ width: 1 })Text('background image position').fontSize(9).width('90%').fontColor(0xCCCCCC)Row().width(100).height(50).backgroundImage('/comment/bg.jpg', ImageRepeat.NoRepeat).backgroundImageSize({ width: 1000, height: 560 }).backgroundImagePosition({ x: -500, y: -300 }).border({ width: 1 })}.width('100%').height('100%').padding({ top: 5 })}
}
2.颜色渐变
1.线性渐变 linearGradient()
{angle?: 线性渐变的起始角度,direction?: 线性渐变的方向,colors: [[颜色1, 颜色1所处位置], [颜色2, 颜色2所处位置], ......],repeating?: 是否重复着色
}
-
angle
:线性渐变的起始角度。0点方向顺时针旋转为正向角度,默认值:180t -
direction
: 线性渐变的方向,设置 angle 后不生效,值为 枚举类型GradientDirection
-
-
Left:从右向左
-
Top:从下向上
-
Right:从左向右
-
Bottom:从上向下
-
LeftTop:从右下 到 左上
-
LeftBottom:从右上 到 左下
-
RightTop:从左下 到 右上
-
RightBottom:从左上 到 右下
// xxx.ets @Entry @Component struct ColorGradientExample {build() {Column({ space: 5 }) {Text('linearGradient').fontSize(12).width('90%').fontColor(0xCCCCCC)Row().width('90%').height(50).linearGradient({angle: 90,colors: [[0xff0000, 0.0], [0x0000ff, 0.3], [0xffff00, 1.0]]})Text('linearGradient Repeat').fontSize(12).width('90%').fontColor(0xCCCCCC)Row().width('90%').height(50).linearGradient({direction: GradientDirection.Left, // 渐变方向repeating: true, // 渐变颜色是否重复colors: [[0xff0000, 0.0], [0x0000ff, 0.3], [0xffff00, 0.5]] // 数组末尾元素占比小于1时满足重复着色效果})}.width('100%').padding({ top: 5 })} }
2.径向渐变 radialGradient()
{center: 径向渐变的中心点坐标,radius: 径向渐变的半径,colors: [[颜色1, 颜色1所处位置], [颜色2, 颜色2所处位置], ......],repeating?: 是否重复着色 }
-
center
:径向渐变的中心点,即相对于当前组件左上角的坐标,写法[x坐标, y坐标]
// xxx.ets @Entry @Component struct ColorGradientExample {build() {Column({ space: 5 }) {Text('radialGradient').fontSize(12).width('90%').fontColor(0xCCCCCC)Row().width(100).height(100).radialGradient({center: [50, 50],radius: 60,colors: [[0xff0000, 0.0], [0x0000ff, 0.3], [0xffff00, 1.0]]})Text('radialGradient Repeat').fontSize(12).width('90%').fontColor(0xCCCCCC)Row().width(100).height(100).radialGradient({center: [50, 50],radius: 60,repeating: true,colors: [[0xff0000, 0.0], [0x0000ff, 0.3], [0xffff00, 0.5]] // 数组末尾元素占比小于1时满足重复着色效果})}.width('100%').padding({ top: 5 })} }
-
-
3.定位属性
改变组件位置
-
绝对定位:
position
,相对父组件左上角进行偏移 -
相对定位:
offset
,相对自身左上角进行偏移1.绝对定位
属性:
position()
参数:
{x: 水平偏移量, y: 垂直偏移量}
偏移量取值
-
数字,单位是
vp
-
百分比,参照父组件尺寸计算结果
@Entry @Component struct Index {build() {Column() {Text('文字内容').width(80).height(40).backgroundColor(Color.Pink).position({x: 0,y: 0})}.width('100%').height(200).backgroundColor('#ccc')} }
绝对定位特点:
-
参照父组件左上角进行偏移
-
绝对定位后的组件不再占用自身原有位置
2.相对定位
属性:offset()
参数:
{x: 水平偏移量, y: 垂直偏移量}
偏移量取值
-
数字,单位是
vp
-
百分比,参照父组件尺寸计算结果
@Entry @Component struct Index {build() {Column() {Text('内容1').width(80).height(40).backgroundColor(Color.Pink)Text('内容2').width(80).height(40).backgroundColor(Color.Orange)// 占位.offset({x: 100,y: -30})Text('内容3').width(80).height(40).backgroundColor(Color.Brown)}.width('100%').height(200).backgroundColor('#ccc')} }
相对定位特点:
-
相对自身左上角进行偏移
-
相对定位后的组件仍然占用自身原有位置
示例
// xxx.ets @Entry @Component struct Example3 {build() {Column({ space: 20 }){Text('position use Edges').fontSize(12).fontColor(0xCCCCCC).width('90%')Row() {Text('bottom:0, right:0').size({ width: '30%', height: '50' }).backgroundColor(0xdeb887).border({ width: 1 }).fontSize(16).textAlign(TextAlign.Center).position({bottom: 0, right: 0})Text('top:0, left:0').size({ width: '30%', height: '50' }).backgroundColor(0xdeb887).border({ width: 1 }).fontSize(16).textAlign(TextAlign.Center).position({top: 0, left: 0})Text('top:10%, left:50%').size({ width: '50%', height: '30' }).backgroundColor(0xbbb2cb).border({ width: 1 }).fontSize(16).textAlign(TextAlign.Center).position({ top: '10%', left: '50%' })Text('bottom:0, left:30').size({ width: '50%', height: '30' }).backgroundColor(0xbbb2cb).border({ width: 1 }).fontSize(16).textAlign(TextAlign.Center).position({ bottom: 0, left: 30 })}.width('90%').height(100).border({ width: 1, style: BorderStyle.Dashed })Text('offset use Edges').fontSize(12).fontColor(0xCCCCCC).width('90%')Row() {Text('1').size({ width: '25%', height: 50 }).backgroundColor(0xdeb887).border({ width: 1 }).fontSize(16).textAlign(TextAlign.Center)Text('2 top:30, left:0').size({ width: '25%', height: 50 }).backgroundColor(0xbbb2cb).border({ width: 1 }).fontSize(16).textAlign(TextAlign.Center).offset({top: 30, left: 0})Text('3').size({ width: '25%', height: 50 }).backgroundColor(0xdeb887).border({ width: 1 }).fontSize(16).textAlign(TextAlign.Center)Text('4 bottom:10, right:30').size({ width: '25%', height: 50 }).backgroundColor(0xbbb2cb).border({ width: 1 }).fontSize(12).textAlign(TextAlign.Center).offset({bottom: 10, right: 30})}.width('90%').height(150).border({ width: 1, style: BorderStyle.Dashed })}.width('100%').margin({ top: 25 })} }
-
-
-
-
3.Z 序控制
定位后的组件,默认后定义的组件在最上面显示,可以通过 zIndex 属性调整显示层级
属性:zIndex(数字)
特点:取值为整数数字,取值越大,显示层级越高
// xxx.ets
@Entry
@Component
struct ZIndexExample {build() {Column() {Stack() {// stack会重叠组件, 默认后定义的在最上面,具有较高zIndex值的元素在zIndex较小的元素前面Text('1, zIndex(2)').size({ width: '40%', height: '30%' }).backgroundColor(0xbbb2cb).zIndex(2)Text('2, default zIndex(1)').size({ width: '70%', height: '50%' }).backgroundColor(0xd2cab3).align(Alignment.TopStart).zIndex(1)Text('3, zIndex(0)').size({ width: '90%', height: '80%' }).backgroundColor(0xc1cbac).align(Alignment.TopStart)}.width('100%').height(200)}.width('100%').height(200)}
}
4.通用属性
1.多态样式stateStyles()
设置组件不同状态的样式。
状态名称 | 类型 | 必填 | 描述 |
---|---|---|---|
normal | ()=>void | 否 | 组件无状态时的样式。 |
pressed | ()=>void | 否 | 组件按下状态的样式。 |
disabled | ()=>void | 否 | 组件禁用状态的样式。 |
focused | ()=>void | 否 | 组件获焦状态的样式。 |
clicked | ()=>void | 否 | 组件点击状态的样式。 |
selected10+ | ()=>void | 否 | 组件选中状态的样式。 |
示例
// xxx.ets
@Entry
@Component
struct Index {@State value: boolean = false@State value2: boolean = false@StylesnormalStyles(): void{.backgroundColor("#E5E5E1")}@StylesselectStyles(): void{.backgroundColor("#ED6F21").borderWidth(2)}build() {Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {Column() {Text('Radio1').fontSize(25)Radio({ value: 'Radio1', group: 'radioGroup1' }).checked(this.value).height(50).width(50).borderWidth(0).borderRadius(30).onClick(() => {this.value = !this.value}).stateStyles({normal: this.normalStyles,selected: this.selectStyles,})}.margin(30)Column() {Text('Radio2').fontSize(25)Radio({ value: 'Radio2', group: 'radioGroup2' }).checked($$this.value2).height(50).width(50).borderWidth(0).borderRadius(30).stateStyles({normal: this.normalStyles,selected: this.selectStyles,})}.margin(30)}.padding({ top: 30 })}
}
2.动画 animation
组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,提升用户体验。支持的属性包括width、height、backgroundColor、opacity、scale、rotate、translate等。
属性:animation
参数: {}
参数 | 描述 |
---|---|
duration | 设置动画时长。默认值:1000单位:毫秒 |
curve | 设置动画曲线默认值:Curve.EaseInOut |
delay | 设置动画延迟执行的时长。默认值:0,不延迟播放。单位:毫秒 |
iterations | 设置播放次数。默认值:1设置为-1时表示无限次播放。设置为0时表示无动画效果。 |
playMode | 动画播放模式,默认播放完成后重头开始播放。默认值:PlayMode.Norma |
tempo | 动画播放速度,值越大动画播放越快,值越小播放越慢,为0时无动画效果, 默认值:1.0 |
// xxx.ets
@Entry
@Component
struct AttrAnimationExample {@State widthSize: number = 250@State heightSize: number = 100@State rotateAngle: number = 0@State flag: boolean = truebuild() {Column() {Button('change size').onClick(() => {if (this.flag) {this.widthSize = 150this.heightSize = 60} else {this.widthSize = 250this.heightSize = 100}this.flag = !this.flag}).margin(30).width(this.widthSize).height(this.heightSize).animation({duration: 2000,curve: Curve.EaseOut,iterations: 3,playMode: //PlayMode.Alternate动画在奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。})Button('change rotate angle').onClick(() => {this.rotateAngle = 90}).margin(50).rotate({ angle: this.rotateAngle }).animation({duration: 1200,curve: Curve.Friction,delay: 500,iterations: -1, // 设置-1表示动画无限循环playMode: PlayMode.Alternate,//期望帧率// expectedFrameRateRange: {// min: 20,// max: 120,// expected: 90,// }})}.width('100%').margin({ top: 20 })}
}
3.图形变换
1.平移
作用:可使组件在以组件左上角为坐标原点的坐标系中进行移动
属性:translate()
参数:{x?: X轴移动距离, y?: Y轴移动距离, z?: Z轴移动距离}
@Entry
@Component
struct Index {build() {Column() {Image($r('app.media.cat')).width(200).aspectRatio(1).stateStyles({normal: {.translate({x: 0})},pressed: {.translate({x: 100})}}).animation({curve: Curve.Linear//表示动画从头到尾的速度都是相同的。})}.padding(20)}
}
2.缩放
作用:分别设置X轴、Y轴、Z轴的缩放比例,默认值为1
属性:scale()
,
参数: {x?: X轴缩放比例, y?: Y轴缩放比例, z?: Z轴缩放比例, centerX?: Y轴中心点坐标, centerY? Y轴中心点坐标}
@Entry
@Component
struct Index {build() {Column() {Image($r('app.media.cat')).width(200).aspectRatio(1).stateStyles({normal: {.scale({x:1, y: 1})},pressed: {.scale({x: 0.8, y: 0.8})}}).animation({curve: Curve.Linear})}.padding(20)}
}
3.旋转
作用:可使组件在以组件左上角为坐标原点的坐标系中进行旋转
属性:rotate()
参数:{angle: 旋转角度, centerX?: Y轴中心点坐标, centerY? Y轴中心点坐标}
@Entry
@Component
struct Index {build() {Column() {Image($r('app.media.cat')).width(200).aspectRatio(1).stateStyles({normal: {.rotate({angle: 0})},pressed: {.rotate({angle: 60})}}).animation({curve: Curve.Linear,})}.padding(20)}
}
3.线性布局(Row,Column)
1.概述
线性布局(LinearLayout)是开发中最常用的布局,通过线性容器Row和Column构建。线性布局是其他布局的基础,其子元素在线性方向上(水平方向和垂直方向)依次排列。线性布局的排列方向由所选容器组件决定,Column容器内子元素按照垂直方向排列,Row容器内子元素按照水平方向排列。根据不同的排列方向,开发者可选择使用Row或Column容器创建线性布局。
Column容器内子元素排列示意图
Row容器内子元素排列示意图
2.间距:space
//自己试一下吧
Column({ space: 20 }) {Text('space: 20').fontSize(15).fontColor(Color.Gray).width('90%')Row().width('90%').height(50).backgroundColor(0xF5DEB3)Row().width('90%').height(50).backgroundColor(0xD2B48C)Row().width('90%').height(50).backgroundColor(0xF5DEB3)
}.width('100%')
//自己试一下吧
Row({ space: 35 }) {Text('space: 35').fontSize(15).fontColor(Color.Gray)Row().width('10%').height(150).backgroundColor(0xF5DEB3)Row().width('10%').height(150).backgroundColor(0xD2B48C)Row().width('10%').height(150).backgroundColor(0xF5DEB3)
}.width('90%')
3.辅轴排列方式
在布局容器内,可以通过alignItems属性设置子元素在交叉轴(排列方向的垂直方向)上的对齐方式。且在各类尺寸屏幕中,表现一致。其中,交叉轴为垂直方向时,取值为VerticalAlign类型,水平方向取值为HorizontalAlign类型。
Column容器内子元素在水平方向上的排列图
//HorizontalAlign.Start:子元素在水平方向左对齐。Column({}) {Column() {}.width('80%').height(50).backgroundColor(0xF5DEB3)Column() {}.width('80%').height(50).backgroundColor(0xD2B48C)Column() {}.width('80%').height(50).backgroundColor(0xF5DEB3)
}.width('100%').alignItems(HorizontalAlign.Start).backgroundColor('rgb(242,242,242)')
Row容器内子元素在垂直方向上的排列图
//VerticalAlign.Top:子元素在垂直方向顶部对齐。
Row({}) {Column() {}.width('20%').height(30).backgroundColor(0xF5DEB3)Column() {}.width('20%').height(30).backgroundColor(0xD2B48C)Column() {}.width('20%').height(30).backgroundColor(0xF5DEB3)
}.width('100%').height(200).alignItems(VerticalAlign.Top).backgroundColor('rgb(242,242,242)')
4.主轴排列方式
Column容器内子元素在垂直方向上的排列图
//去试一下吧
Column({}) {Column() {}.width('80%').height(50).backgroundColor(0xF5DEB3)Column() {}.width('80%').height(50).backgroundColor(0xD2B48C)Column() {}.width('80%').height(50).backgroundColor(0xF5DEB3)
}.width('100%').height(300).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.Start)
Row容器内子元素在水平方向上的排列图
//去试一下吧
Row({}) {Column() {}.width('20%').height(30).backgroundColor(0xF5DEB3)Column() {}.width('20%').height(30).backgroundColor(0xD2B48C)Column() {}.width('20%').height(30).backgroundColor(0xF5DEB3)
}.width('100%').height(200).backgroundColor('rgb(242,242,242)').justifyContent(FlexAlign.Start)
5.自适应拉伸
在线性布局下,常用空白填充组件Blank,在容器主轴方向自动填充空白空间,达到自适应拉伸效果。Row和Column作为容器,只需要添加宽高为百分比,当屏幕宽高发生变化时,会产生自适应效果。
@Entry
@Component
struct BlankExample {build() {Column() {Row() {Text('Bluetooth').fontSize(18)Blank()Toggle({ type: ToggleType.Switch, isOn: true })}.backgroundColor(0xFFFFFF).borderRadius(15).padding({ left: 12 }).width('100%')}.backgroundColor(0xEFEFEF).padding(20).width('100%')}
}
6.自适应缩放
自适应缩放是指子元素随容器尺寸的变化而按照预设的比例自动调整尺寸,适应各种不同大小的设备。在线性布局中,可以使用以下两种方法实现自适应缩放。
- 父容器尺寸确定时,使用layoutWeight属性设置子元素和兄弟元素在主轴上的权重,忽略元素本身尺寸设置,使它们在任意尺寸的设备下自适应占满剩余空间。
@Entry
@Component
struct layoutWeightExample {build() {Column() {Text('1:2:3').width('100%')Row() {Column() {Text('layoutWeight(1)').textAlign(TextAlign.Center)}.layoutWeight(1).backgroundColor(0xF5DEB3).height('100%')Column() {Text('layoutWeight(2)').textAlign(TextAlign.Center)}.layoutWeight(2).backgroundColor(0xD2B48C).height('100%')Column() {Text('layoutWeight(3)').textAlign(TextAlign.Center)}.layoutWeight(3).backgroundColor(0xF5DEB3).height('100%')}.backgroundColor(0xffd306).height('30%')}}
}
7.自适应延伸
使用Scroll组件:在线性布局中,开发者可以进行垂直方向或者水平方向的布局。当一屏无法完全显示时,可以在Column或Row组件的外层包裹一个可滚动的容器组件Scroll来实现可滑动的线性布局。
//垂直方向布局中使用Scroll组件
@Entry
@Component
struct ScrollExample {scroller: Scroller = new Scroller();private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];build() {Scroll(this.scroller) {Column() {ForEach(this.arr, (item?:number|undefined) => {if(item){Text(item.toString()).width('90%').height(150).backgroundColor(0xFFFFFF).borderRadius(15).fontSize(16).textAlign(TextAlign.Center).margin({ top: 10 })}}, (item:number) => item.toString())}.width('100%')}.backgroundColor(0xDCDCDC).scrollable(ScrollDirection.Vertical) // 滚动方向为垂直方向.scrollBar(BarState.On) // 滚动条常驻显示.scrollBarColor(Color.Gray) // 滚动条颜色.scrollBarWidth(10) // 滚动条宽度.edgeEffect(EdgeEffect.Spring) // 滚动到边沿后回弹}
}
-------------------------(第一次)今天的更新结束了,感觉对你有帮助的话就点点关注吧❤-----------------
4.弹性布局(Flex)
(使用线性布局一般就可以解决大部分的问题了,这是典型应用场景)
1.概述(四个关键点,布局方向,换行,主轴排列方式,辅轴排列方式)
弹性布局(Flex)提供更加有效的方式对容器中的子元素进行排列、对齐和分配剩余空间。常用于页面头部导航栏的均匀分布、页面框架的搭建、多行数据的排列等。
2.布局方向
在弹性布局中,容器的子元素可以按照任意方向排列。通过设置参数direction,可以决定主轴的方向,从而控制子元素的排列方向。
FlexDirection.Row(默认值):主轴为水平方向,子元素从起始端沿着水平方向开始排布。
Flex({ direction: FlexDirection.Row }) {Text('1').width('33%').height(50).backgroundColor(0xF5DEB3)Text('2').width('33%').height(50).backgroundColor(0xD2B48C)Text('3').width('33%').height(50).backgroundColor(0xF5DEB3)
}
.height(70)
.width('90%')
.padding(10)
.backgroundColor(0xAFEEEE)
**FlexDirection.Column:**主轴为垂直方向,子元素从起始端沿着垂直方向开始排布。
Flex({ direction: FlexDirection.Column }) {Text('1').width('100%').height(50).backgroundColor(0xF5DEB3)Text('2').width('100%').height(50).backgroundColor(0xD2B48C)Text('3').width('100%').height(50).backgroundColor(0xF5DEB3)
}
.height(70)
.width('90%')
.padding(10)
.backgroundColor(0xAFEEEE)
3.布局换行
弹性布局分为单行布局和多行布局。默认情况下,Flex容器中的子元素都排在一条线(又称“轴线”)上。wrap属性控制当子元素主轴尺寸之和大于容器主轴尺寸时,Flex是单行布局还是多行布局。在多行布局时,通过交叉轴方向,确认新行排列方向。
FlexWrap. NoWrap(默认值):不换行。如果子元素的宽度总和大于父元素的宽度,则子元素会被压缩宽度。
Flex({ wrap: FlexWrap.NoWrap }) {Text('1').width('50%').height(50).backgroundColor(0xF5DEB3)Text('2').width('50%').height(50).backgroundColor(0xD2B48C)Text('3').width('50%').height(50).backgroundColor(0xF5DEB3)
}
.width('90%')
.padding(10)
.backgroundColor(0xAFEEEE)
FlexWrap. Wrap:换行,每一行子元素按照主轴方向排列
Flex({ wrap: FlexWrap.Wrap }) {Text('1').width('50%').height(50).backgroundColor(0xF5DEB3)Text('2').width('50%').height(50).backgroundColor(0xD2B48C)Text('3').width('50%').height(50).backgroundColor(0xD2B48C)
}
.width('90%')
.padding(10)
.backgroundColor(0xAFEEEE)
4.主轴对齐方式
通过justifyContent参数设置子元素在主轴方向的对齐方式
5.交叉轴对齐方式
容器和子元素都可以设置交叉轴对齐方式,且子元素设置的对齐方式优先级较高。
1.容器组件设置交叉轴对齐
ItemAlign.Auto:使用Flex容器中默认配置。
ItemAlign.Start:交叉轴方向首部对齐。
ItemAlign.Center:交叉轴方向居中对齐
let SWh:Record<string,number|string> = { 'width': '90%', 'height': 80 }
Flex({ alignItems: ItemAlign.Center }) { Text('1').width('33%').height(30).backgroundColor(0xF5DEB3) Text('2').width('33%').height(40).backgroundColor(0xD2B48C) Text('3').width('33%').height(50).backgroundColor(0xF5DEB3)
}
.size(SWh)
.padding(10)
.backgroundColor(0xAFEEEE)
ItemAlign.End:交叉轴方向底部对齐。
2.子元素设置交叉轴对齐(上一个就可以实现)
场景示例
使用弹性布局,可以实现子元素沿水平方向排列,两端对齐,子元素间距平分,垂直方向上子元素居中的效果。
@Entry
@Component
struct FlexExample {build() {Column() {Column({ space: 5 }) {Flex({ direction: FlexDirection.Row, wrap: FlexWrap.NoWrap, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {Text('1').width('30%').height(50).backgroundColor(0xF5DEB3)Text('2').width('30%').height(50).backgroundColor(0xD2B48C)Text('3').width('30%').height(50).backgroundColor(0xF5DEB3)}.height(70).width('90%').backgroundColor(0xAFEEEE)}.width('100%').margin({ top: 5 })}.width('100%') }
}
5.层叠布局(Stack)
1.概述
层叠布局(StackLayout)用于在屏幕上预留一块区域来显示组件中的元素,提供元素可以重叠的布局。层叠布局通过Stack容器组件实现位置的固定定位与层叠,容器中的子元素依次入栈,后一个子元素覆盖前一个子元素,子元素可以叠加,也可以设置位置。
层叠布局具有较强的页面层叠、位置定位能力,其使用场景有广告、卡片层叠效果等。
2.开发布局
Stack组件为容器组件,容器内可包含各种子元素。其中子元素默认进行居中堆叠。子元素被约束在Stack下,进行自己的样式定义以及排列。
// xxx.ets
let MTop:Record<string,number> = { 'top': 50 }@Entry
@Component
struct StackExample {build() {Column(){Stack({ }) {Column(){}.width('90%').height('100%').backgroundColor('#ff58b87c')Text('text').width('60%').height('60%').backgroundColor('#ffc3f6aa')Button('button').width('30%').height('30%').backgroundColor('#ff8ff3eb').fontColor('#000')}.width('100%').height(150).margin(MTop)}}
}
3.对齐方式(alignContent)
Stack组件通过alignContent参数实现位置的相对移动。如图2所示,支持九种对齐方式。
4.Z序控制
Stack容器中兄弟组件显示层级关系可以通过Z序控制的zIndex属性改变。zIndex值越大,显示层级越高,即zIndex值大的组件会覆盖在zIndex值小的组件上方。
在层叠布局中,如果后面子元素尺寸大于前面子元素尺寸,则前面子元素完全隐藏
Stack({ alignContent: Alignment.BottomStart }) {Column() {Text('Stack子元素1').fontSize(20)}.width(100).height(100).backgroundColor(0xffd306).zIndex(2)Column() {Text('Stack子元素2').fontSize(20)}.width(150).height(150).backgroundColor(Color.Pink).zIndex(1)Column() {Text('Stack子元素3').fontSize(20)}.width(200).height(200).backgroundColor(Color.Grey)
}.width(350).height(350).backgroundColor(0xe0e0e0)
场景示例
使用层叠布局快速搭建页面。
@Entry
@Component
struct StackSample {private arr: string[] = ['APP1', 'APP2', 'APP3', 'APP4', 'APP5', 'APP6', 'APP7', 'APP8'];build() {Stack({ alignContent: Alignment.Bottom }) {Flex({ wrap: FlexWrap.Wrap }) {ForEach(this.arr, (item:string) => {Text(item).width(100).height(100).fontSize(16).margin(10).textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)}, (item:string):string => item)}.width('100%').height('100%')Flex({ justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {Text('联系人').fontSize(16)Text('设置').fontSize(16)Text('短信').fontSize(16)}.width('50%').height(50).backgroundColor('#16302e2e').margin({ bottom: 15 }).borderRadius(15)}.width('100%').height('100%').backgroundColor('#CFD0CF')}
}
6.轮播(Swiper)🎈
1.概述
Swiper组件提供滑动轮播显示的能力。Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。通常,在一些应用首页显示推荐的内容时,需要用到轮播显示的能力。
针对复杂页面场景,可以使用 Swiper 组件的预加载机制,利用主线程的空闲时间来提前构建和布局绘制组件,优化滑动体验。
布局与约束
Swiper作为一个容器组件,如果设置了自身尺寸属性,则在轮播显示过程中均以该尺寸生效。如果自身尺寸属性未被设置,则分两种情况:如果设置了prevMargin或者nextMargin属性,则Swiper自身尺寸会跟随其父组件;如果未设置prevMargin或者nextMargin属性,则会自动根据子组件的大小设置自身的尺寸。0
loop | boolean | 是否开启循环。设置为true时表示开启循环, |
---|---|---|
autoPlay | boolean | 子组件是否自动播放。默认值:false**说明:**loop为false时,自动轮播到最后一页时停止轮播。手势切换后不是最后一页时继续播放。 |
interval | number | 使用自动播放时播放的时间间隔,单位为毫秒。默认值:3000 |
vertical | boolean | 是否为纵向滑动。默认值:false |
indicator | Indicator.dot()/digit() | 导航点样式/导航数字样式 |
2.循环播放
通过loop属性控制是否循环播放,该属性默认值为true。
当loop为true时,在显示第一页或最后一页时,可以继续往前切换到前一页或者往后切换到后一页。如果loop为false,则在第一页或最后一页时,无法继续向前或者向后切换页面。
-
loop为true
Swiper() {Text('0').width('90%').height('100%').backgroundColor(Color.Gray).textAlign(TextAlign.Center).fontSize(30)Text('1').width('90%').height('100%').backgroundColor(Color.Green).textAlign(TextAlign.Center).fontSize(30)Text('2').width('90%').height('100%').backgroundColor(Color.Pink).textAlign(TextAlign.Center).fontSize(30) } .loop(true)
Swiper() {// ...
}
.indicator(Indicator.dot().left(0).itemWidth(15).itemHeight(15).selectedItemWidth(30).selectedItemHeight(15).color(Color.Red).selectedColor(Color.Blue)
)
Swiper通过设置displayArrow属性,可以控制导航点箭头的大小、位置、颜色,底板的大小及颜色,以及鼠标悬停时是否显示箭头。
-
箭头使用默认样式
Swiper() {// ... } .displayArrow(true, false)
-
自定义箭头样式
-
箭头显示在组件两侧,大小为18vp,导航点箭头颜色设为蓝色。
Swiper() {// ... } .displayArrow({ showBackground: true,//设置箭头底板是否显示。isSidebarMiddle: true,//设置箭头显示位置。backgroundSize: 24,//设置底板大小。backgroundColor: Color.White,//设置底板颜色,在导航点两侧显示arrowSize: 18,//设置箭头大小arrowColor: Color.Blue//箭头颜色}, false)
-
4.控制器切换
@Entry
@Component
struct SwiperDemo {private swiperController: SwiperController = new SwiperController();build() {Column({ space: 5 }) {Swiper(this.swiperController) {Text('0').width(250).height(250).backgroundColor(Color.Gray).textAlign(TextAlign.Center).fontSize(30)Text('1').width(250).height(250).backgroundColor(Color.Green).textAlign(TextAlign.Center).fontSize(30)Text('2').width(250).height(250).backgroundColor(Color.Pink).textAlign(TextAlign.Center).fontSize(30)}.indicator(true)Row({ space: 12 }) {Button('showNext').onClick(() => {this.swiperController.showNext(); // 通过controller切换到后一页})Button('showPrevious').onClick(() => {this.swiperController.showPrevious(); // 通过controller切换到前一页})}.margin(5)}.width('100%').margin({ top: 5 })}
}
5.轮播方向
Swiper支持水平和垂直方向上进行轮播,主要通过vertical属性控制。
当vertical为true时,表示在垂直方向上进行轮播;为false时,表示在水平方向上进行轮播。vertical默认值为false。
-
设置水平方向上轮播
Swiper() {// ... } .indicator(true) .vertical(false)
-
设置垂直方向轮播。
Swiper() {// ... } .indicator(true) .vertical(true)
6.每页显示多个子页面
Swiper支持在一个页面内同时显示多个子组件,通过displayCount属性设置。
Swiper() {Text('0').width(250).height(250).backgroundColor(Color.Gray).textAlign(TextAlign.Center).fontSize(30)Text('1').width(250).height(250).backgroundColor(Color.Green).textAlign(TextAlign.Center).fontSize(30)Text('2').width(250).height(250).backgroundColor(Color.Pink).textAlign(TextAlign.Center).fontSize(30)Text('3').width(250).height(250).backgroundColor(Color.Blue).textAlign(TextAlign.Center).fontSize(30) } .indicator(true) .displayCount(2)
-
5.组件
1.使用文本
文本显示 (Text/Span)-使用文本-UI开发 (ArkTS声明式开发范式)-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者 (huawei.com)
1.文本显示(Text/Span)
a.常见属性
属性 | 描述 |
---|---|
fontSize | 字体大小 |
fontColor | 字体颜色 |
fontStyle | 字体样式 |
fontWeight | 字体粗细 |
lineHeight | 文本行高 |
decoration | 文本修饰线及颜色 |
textAlign | 水平方向Text对齐方式 |
align | 垂直方向对齐方式 |
textIndent | 文本首行缩进 |
b.通过textCase设置文字一直保持大写或者小写状态。
解释Text() {Span('I am Upper-span').fontSize(12).textCase(TextCase.UpperCase)
}
.borderWidth(1)
.padding(10)
c.通过copyOption属性设置文本是否可复制粘贴。
Text("这是一段可复制文本").fontSize(30).copyOption(CopyOptions.InApp)
d.添加子组件
创建Span。
Span组件需要写到Text组件内,单独写Span组件不会显示信息,Text与Span同时配置文本内容时,Span内容覆盖Text内容。
解释Text('我是Text') {Span('我是Span')
}
.padding(10)
.borderWidth(1)
*e.场景示例*
解释// 试一试吧
@Entry
@Component
struct TextExample {build() {Column() {Row() {Text("1").fontSize(14).fontColor(Color.Red).margin({ left: 10, right: 10 })Text("我是热搜词条1").fontSize(12).fontColor(Color.Blue).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis }).fontWeight(300)Text("爆").margin({ left: 6 }).textAlign(TextAlign.Center).fontSize(10).fontColor(Color.White).fontWeight(600).backgroundColor(0x770100).borderRadius(5).width(15).height(14)}.width('100%').margin(5)Row() {Text("2").fontSize(14).fontColor(Color.Red).margin({ left: 10, right: 10 })Text("我是热搜词条2 我是热搜词条2 我是热搜词条2 我是热搜词条2 我是热搜词条2").fontSize(12).fontColor(Color.Blue).fontWeight(300).constraintSize({ maxWidth: 200 }).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })Text("热").margin({ left: 6 }).textAlign(TextAlign.Center).fontSize(10).fontColor(Color.White).fontWeight(600).backgroundColor(0xCC5500).borderRadius(5).width(15).height(14)}.width('100%').margin(5)Row() {Text("3").fontSize(14).fontColor(Color.Orange).margin({ left: 10, right: 10 })Text("我是热搜词条3").fontSize(12).fontColor(Color.Blue).fontWeight(300).maxLines(1).constraintSize({ maxWidth: 200 }).textOverflow({ overflow: TextOverflow.Ellipsis })Text("热").margin({ left: 6 }).textAlign(TextAlign.Center).fontSize(10).fontColor(Color.White).fontWeight(600).backgroundColor(0xCC5500).borderRadius(5).width(15).height(14)}.width('100%').margin(5)Row() {Text("4").fontSize(14).fontColor(Color.Grey).margin({ left: 10, right: 10 })Text("我是热搜词条4 我是热搜词条4 我是热搜词条4 我是热搜词条4 我是热搜词条4").fontSize(12).fontColor(Color.Blue).fontWeight(300).constraintSize({ maxWidth: 200 }).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })}.width('100%').margin(5)}.width('100%')}
}
2.文本输入 (TextInput/TextArea)🎈
1.概述
TextInput、TextArea是输入框组件,通常用于响应用户的输入操作,比如评论区的输入、聊天框的输入、表格的输入等,也可以结合其它组件构建功能页面,例如登录注册页面。具体用法请参考TextInput、TextArea。
TextInput常用参数
参数名 | 类型 | 是否必填 | 说明 |
---|---|---|---|
placeholder | ResourceStr | 否 | 设置无输入时的提示文本。 |
text | ResourceStr | 否 | 设置输入框当前的文本内容。从API version 10开始,该参数支持$$双向绑定变量。 |
常用属性
名称 | 参数类型 | 描述 |
---|---|---|
type | InputType | 设置输入框类型。默认值:InputType.Normal |
showUnderline | boolean | 设置是否开启下划线。下划线默认颜色为’#33182431’,默认粗细为1px,文本框尺寸48vp(下划线只支持InputType.Normal类型)。默认值:false |
passwordIcon | PasswordIcon | onIconSrc:输入状态时图标offIconSrc:隐藏状态时图标 |
placeholderColor | ResourceColor | 设置placeholder文本颜色。默认值跟随主题。 |
TextArea常用参数
参数名 | 类型 | 是否必填 | 说明 |
---|---|---|---|
placeholder | ResourceStr | 否 | 设置无输入时的提示文本。 |
text | ResourceStr | 否 | 设置输入框当前的文本内容。从API version 10开始,该参数支持$$双向绑定变量。 |
常用属性
名称 | 参数类型 | 描述 |
---|---|---|
type | InputType | 设置输入框类型。默认值:InputType.Normal |
placeholderColor | ResourceColor | 设置placeholder文本颜色。默认值跟随主题。 |
showCounter | value: boolean, options11+?: InputCounterOptions | 参数value为true时,才能设置options,文本框开启计数下标功能,需要配合maxlength(设置最大字符限制)一起使用。 |
maxLength | number | 设置文本的最大输入字符数。 默认不设置最大输入字符数限制。 到达文本最大字符限制,将无法继续输入字符,同时边框变为红色。 |
… |
2.创建输入框
TextInput为单行输入框、TextArea为多行输入框。通过以下接口来创建。
TextInput(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextInputController})TextArea(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextAreaController})
单行输入框/多行输入框
TextInput()
TextArea()
//多行输入框文字超出一行时会自动折行。
TextArea({text:"我是TextArea我是TextArea我是TextArea我是TextArea"}).width(300)
3.设置输入框类型
TextInput有9种可选类型,分别为Normal基本输入模式、Password密码输入模式、Email邮箱地址输入模式、Number纯数字输入模式、PhoneNumber电话号码输入模式、USER_NAME用户名输入模式、NEW_PASSWORD新密码输入模式、NUMBER_PASSWORD纯数字密码输入模式、NUMBER_DECIMAL带小数点的数字输入模式。通过type属性进行设置:
密码输入模式
TextInput().type(InputType.Password)
4.自定义样式
设置无输入时的提示文本。
设置输入框当前的文本内容。
添加backgroundColor改变输入框的背景颜色。
更丰富的样式可以结合通用属性实现。
TextInput({placeholder:'我是提示文本'})TextInput({placeholder:'我是提示文本',text:'我是当前文本内容'})TextInput({placeholder:'我是提示文本',text:'我是当前文本内容'}).backgroundColor(Color.Pink)
5.添加事件
文本框主要用于获取用户输入的信息,把信息处理成数据进行上传,绑定onChange事件可以获取输入框内改变的内容。用户也可以使用通用事件来进行相应的交互操作。
TextInput().onChange((value: string) => {console.info(value);}).onFocus(() => {console.info('获取焦点');})
6.示例
@Entry
@Component
struct TextInputSample {build() {Column() {TextInput({ placeholder: 'input your username' }).margin({ top: 20 }).onSubmit((EnterKeyType)=>{console.info(EnterKeyType+'输入法回车键的类型值')})TextInput({ placeholder: 'input your password' }).type(InputType.Password).margin({ top: 20 }).onSubmit((EnterKeyType)=>{console.info(EnterKeyType+'输入法回车键的类型值')})Button('Sign in').width(150).margin({ top: 20 })}.padding(20)}
}
7.$$语法:内置组件双向同步(Vue里面的v-model双向数据绑定)
$$运算符为系统内置组件提供TS变量的引用,使得TS变量和系统内置组件的内部状态保持同步。
内部状态具体指什么取决于组件。例如,TextInput组件的text参数。
// xxx.ets
@Entry
@Component
struct TextInputExample {@State text: string = ''controller: TextInputController = new TextInputController()build() {Column({ space: 20 }) {Text(this.text)TextInput({ text: $$this.text, placeholder: 'input your word...', controller: this.controller }).placeholderColor(Color.Grey).placeholderFont({ size: 14, weight: 400 }).caretColor(Color.Blue).width(300)}.width('100%').height('100%').justifyContent(FlexAlign.Center)}
}
2.使用图片(Image)
1.概述
开发者经常需要在应用中显示一些图片,例如:按钮中的icon、网络图片、本地图片等。在应用中显示图片需要使用Image组件实现,Image支持多种图片格式,包括png、jpg、bmp、svg、gif和heif,具体用法请参考Image组件。
2.加载图片
Image(src: PixelMap | ResourceStr | DrawableDescriptor)
a.本地资源
创建文件夹,将本地图片放入ets文件夹下的任意位置。
Image组件引入本地图片路径,即可显示图片(根目录为ets文件夹)
Image('images/view.jpg')
.width(200)
b.网络资源
引入网络图片需申请权限ohos.permission.INTERNET,具体申请方式请参考声明权限。此时,Image组件的src参数为网络图片的链接。
当前Image组件仅支持加载简单网络图片。
Image组件首次加载网络图片时,需要请求网络资源,非首次加载时,默认从缓存中直接读取图片,更多图片缓存设置请参考setImageCacheCount、setImageRawDataCacheSize、setImageFileCacheSize。但是,这三个图片缓存接口并不灵活,且后续不继续演进,对于复杂情况,更推荐使用ImageKnife。
Image('https://www.example.com/example.JPG') // 实际使用时请替换为真实地址
c.Resource资源
使用资源格式可以跨包/跨模块引入图片,resources文件夹下的图片都可以通过$r资源接口读 取到并转换到Resource格式。
//调用方式
Image($r('app.media.icon'))
还可以将图片放在rawfile文件夹下。
Image($rawfile('example1.png'))
3.显示矢量图
Image组件可显示矢量图(svg格式的图片),支持的svg标签为:svg、rect、circle、ellipse、path、line、polyline、polygon和animate。
svg格式的图片可以使用fillColor属性改变图片的绘制颜色。
Image($r('app.media.cloud')).width(50).fillColor(Color.Blue)
原始图片
fillColor添加填充色后的图片
4.组件属性
属性 | 描述 |
---|---|
width | 宽度(通用属性) |
height | 高度(通用属性) |
aspectRatio | 宽高比(通用属性) |
alt | 加载时显示的占位图,支持本地图片(png、jpg、bmp、svg和gif类型),不支持网络图片。 |
objectFit | 设置图片的填充效果。默认值:ImageFit.Cover |
属性:objectFit
参数类型:枚举 ImageFit
-
**Contain:**图片宽或高缩放到与组件尺寸相同则停止缩放,可能导致组件有空白(等比缩放)
-
**Cover:**默认效果,图片缩放到完全覆盖组件范围,可能导致图片显示不完整(等比缩放)
-
**Fill:**图片缩放至充满组件(不等比缩放)
设置图片渲染模式
通过renderMode属性设置图片的渲染模式为原色或黑白。
解释@Entry @Component struct MyComponent {build() {Column({ space: 10 }) {Row({ space: 50 }) {Image($r('app.media.example'))// 设置图片的渲染模式为原色 .renderMode(ImageRenderMode.Original).width(100).height(100).border({ width: 1 })// overlay是通用属性,用于在组件上显示说明文字.overlay('Original', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })Image($r('app.media.example'))// 设置图片的渲染模式为黑白.renderMode(ImageRenderMode.Template).width(100).height(100).border({ width: 1 }).overlay('Template', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })}}.height(150).width('100%').padding({ top: 20,right: 10 })} }
-----------------------------(第二次)今天更新结束觉得写的不错就点点关注吧❤---------------------------
3.按钮(Button)
1.创建按钮
Button通过调用接口来创建,接口调用有以下两种形式:
1.创建不包含子组件的按钮。
其中,label用来设置按钮文字,type用于设置Button类型,stateEffect属性设置Button是否开启点击效果。
解释Button('Ok', { type: ButtonType.Normal, stateEffect: true }) .borderRadius(8) .backgroundColor(0x317aff) .width(90).height(40)
2.创建包含子组件的按钮
只支持包含一个子组件,子组件可以是基础组件或者容器组件。
解释Button({ type: ButtonType.Normal, stateEffect: true }) {Row() {Image($r('app.media.loading')).width(20).height(40).margin({ left: 12 })Text('loading').fontSize(12).fontColor(0xffffff).margin({ left: 5, right: 12 })}.alignItems(VerticalAlign.Center)
}.borderRadius(8).backgroundColor(0x317aff).width(90).height(40)
3.设置按钮类型
Button有三种可选类型,分别为胶囊类型(Capsule)、圆形按钮(Circle)和普通按钮(Normal),通过type进行设置。
-
胶囊按钮(默认类型)
此类型按钮的圆角自动设置为高度的一半,不支持通过borderRadius属性重新设置圆角。
解释Button('Disable', { type: ButtonType.Capsule, stateEffect: false }) .backgroundColor(0x317aff) .width(90).height(40)
圆形按钮(Circle)
此类型按钮为圆形,不支持通过borderRadius属性重新设置圆角。
解释Button('Circle', { type: ButtonType.Circle, stateEffect: false }) .backgroundColor(0x317aff) .width(90) .height(90)
普通按钮(Normal)
此类型的按钮默认圆角为0,支持通过borderRadius属性重新设置圆角。
解释Button('Ok', { type: ButtonType.Normal, stateEffect: true }) .borderRadius(8) .backgroundColor(0x317aff) .width(90).height(40)
4.自定义样式
创建功能型按钮。
为删除操作创建一个按钮。
解释let MarLeft: Record<string, number> = { 'left': 20 }
Button({ type: ButtonType.Circle, stateEffect: true }) {Image($r('app.media.ic_public_delete_filled')).width(30).height(30)
}.width(55).height(55).margin(MarLeft).backgroundColor(0xF55A42)
n(‘Ok’, { type: ButtonType.Normal, stateEffect: true })
.borderRadius(8)
.backgroundColor(0x317aff)
.width(90)
.height(40)
#### **2.创建包含子组件的按钮**只支持包含一个子组件,子组件可以是基础组件或者容器组件。```typescript
解释Button({ type: ButtonType.Normal, stateEffect: true }) {Row() {Image($r('app.media.loading')).width(20).height(40).margin({ left: 12 })Text('loading').fontSize(12).fontColor(0xffffff).margin({ left: 5, right: 12 })}.alignItems(VerticalAlign.Center)
}.borderRadius(8).backgroundColor(0x317aff).width(90).height(40)
3.设置按钮类型
Button有三种可选类型,分别为胶囊类型(Capsule)、圆形按钮(Circle)和普通按钮(Normal),通过type进行设置。
-
胶囊按钮(默认类型)
此类型按钮的圆角自动设置为高度的一半,不支持通过borderRadius属性重新设置圆角。
解释Button('Disable', { type: ButtonType.Capsule, stateEffect: false }) .backgroundColor(0x317aff) .width(90).height(40)
圆形按钮(Circle)
此类型按钮为圆形,不支持通过borderRadius属性重新设置圆角。
解释Button('Circle', { type: ButtonType.Circle, stateEffect: false }) .backgroundColor(0x317aff) .width(90) .height(90)
普通按钮(Normal)
此类型的按钮默认圆角为0,支持通过borderRadius属性重新设置圆角。
解释Button('Ok', { type: ButtonType.Normal, stateEffect: true }) .borderRadius(8) .backgroundColor(0x317aff) .width(90).height(40)
4.自定义样式
创建功能型按钮。
为删除操作创建一个按钮。
解释let MarLeft: Record<string, number> = { 'left': 20 }
Button({ type: ButtonType.Circle, stateEffect: true }) {Image($r('app.media.ic_public_delete_filled')).width(30).height(30)
}.width(55).height(55).margin(MarLeft).backgroundColor(0xF55A42)