基础组件
索引组件---AlphabetIndexer(相当于安卓的seedbar)
使用:AlphabetIndexer(value: {arrayValue: Array<string>, selected: number})
空白填充组件---Blank(占位使用,当父组件为Row/Column/Flex时生效)
使用:Blank(min?: number | string)
按钮组件---Button
使用:Button(options?: {type?: ButtonType, stateEffect?: boolean})-有子组件
Button(label?: ResourceStr, options?: { type?: ButtonType, stateEffect?: boolean })-无子组件
多选框组件---Checkbox
使用:Checkbox(options?: {name?: string, group?: string })
多选框组组件---CheckboxGroup
使用:CheckboxGroup(options?: { group?: string })
单选框---Radio
使用:Radio(options: {value: string, group: string})
例如:Radio({ value: 'Radio3', group: 'radioGroup' }).checked(false)
.height(50)
.width(50)
.onChange((isChecked: boolean) => {
console.log('Radio3 status is ' + isChecked)
})
开关/状态按钮----Toggle
使用:Toggle(options: { type: ToggleType, isOn?: boolean })(仅当ToggleType为Button时可包含子组件)
例如:Toggle({ type: ToggleType.Switch, isOn: false })
.selectedColor('#007DFF')
.switchPointColor('#FFFFFF')
.onChange((isOn: boolean) => {
console.info('Component status:' + isOn)
})
数据面板组件---DataPanel(百分比图标组件,可作为进度条使用)
使用:DataPanel(options:{values: number[], max?: number, type?: DataPanelType})
日期选择器组件---DatePicker
使用:DatePicker(options?: {start?: Date, end?: Date, selected?: Date})
分隔器组件---Divider(安卓中的分割线,包含什么列表或者模块中间的线)
使用:Divider()
数据量规图表组件---Gauge(环形图表)
使用:Gauge({ value: 75 })
.width(200).height(200)
.colors([[0x317AF7, 1], [0x5BA854, 1], [0xE08C3A, 1], [0x9C554B, 1]])
图片组件---Image
使用:Image(src: string | PixelMap | Resource)
例如: // 加载gif格式图片
Image($r('app.media.loading'))
.width(110).height(110).margin(15)
.overlay('gif', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
帧动画组件---ImageAnimator(类似于无法左右滑动但是可以切换的banner)
使用:ImageAnimator()
例如:ImageAnimator()
.images([
{
src: $r('app.media.img1')
},
{
src: $r('app.media.img2')
},
{
src: $r('app.media.img3')
},
{
src: $r('app.media.img4')
}
])
.duration(2000)
.state(this.state).reverse(this.reverse)
.fillMode(FillMode.None).iterations(this.iterations).width(340).height(240)
.margin({ top: 100 })
.onStart(() => {
console.info('Start')
})
.onPause(() => {
console.info('Pause')
})
.onRepeat(() => {
console.info('Repeat')
})
.onCancel(() => {
console.info('Cancel')
})
.onFinish(() => {
console.info('Finish')
this.state = AnimationStatus.Stopped
})
显示加载动效的组件---LoadingProgress
使用:LoadingProgress()
.color(Color.Blue)
跑马灯---Marquee
使用:Marquee(value: { start: boolean, step?: number, loop?: number, fromStart?: boolean, src: string })
例如:Marquee({
start: this.start,
step: this.step,
loop: this.loop,
fromStart: this.fromStart,
src: this.src
})
垂直列表形式显示的菜单---Menu
使用:Menu()
例如:Menu() {
MenuItem({ startIcon: $r("app.media.icon"), content: "菜单选项" })
MenuItem({ startIcon: $r("app.media.icon"), content: "菜单选项" })
.enabled(false)
MenuItem({
startIcon: this.iconStr,
content: "菜单选项",
endIcon: $r("app.media.arrow_right_filled"),
builder: this.SubMenu.bind(this)
})
MenuItemGroup({ header: '小标题' }) {
MenuItem({ content: "菜单选项" })
.selectIcon(true)
.selected(this.select)
.onChange((selected) => {
console.info("menuItem select" + selected);
this.iconStr2 = $r("app.media.icon");
})
MenuItem({
startIcon: $r("app.media.view_list_filled"),
content: "菜单选项",
endIcon: $r("app.media.arrow_right_filled"),
builder: this.SubMenu.bind(this)
})
}
MenuItem({
startIcon: this.iconStr2,
content: "菜单选项",
endIcon: $r("app.media.arrow_right_filled")
})
}
展示菜单Menu中具体的item菜单项---MenuItem
使用:MenuItem(value?: MenuItemOptions| CustomBuilder)
展示菜单MenuItem的分组---MenuItemGroup
使用:MenuItemGroup(value?: MenuItemGroupOptions)
Page页面的根容器---Navigation(通过属性设置来展示页面的标题栏、工具栏、导航栏等)
使用:Navigation()
例如:Navigation() {
TextInput({ placeholder: 'search...' })
.width('90%')
.height(40)
.backgroundColor('#FFFFFF')
.margin({ top: 8 })
List({ space: 12, initialIndex: 0 }) {
ForEach(this.arr, (item) => {
ListItem() {
Text('' + item)
.width('90%')
.height(72)
.backgroundColor('#FFFFFF')
.borderRadius(24)
.fontSize(16)
.fontWeight(500)
.textAlign(TextAlign.Center)
}.editable(true)
}, item => item)
}
.height(324)
.width('100%')
.margin({ top: 12, left: '10%' })
}
.title(this.NavigationTitle)
.menus(this.NavigationMenus)
.titleMode(NavigationTitleMode.Full)
.toolBar(this.NavigationToolbar)
.hideTitleBar(false)
.hideToolBar(false)
.onTitleModeChange((titleModel: NavigationTitleMode) => {
console.info('titleMode' + titleModel)
})
导航组件---NavRouter
使用:NavRouter()
例如:NavRouter() {
Row() {
Row().width(30).height(30).borderRadius(30).margin({ left: 3, right: 10 }).backgroundColor(Color.Pink)
Text(`WLAN`)
.fontSize(22)
.fontWeight(500)
.textAlign(TextAlign.Center)
}
.width('90%')
.height(72)
NavDestination() {
Flex({ direction: FlexDirection.Row }) {
Text('未找到可用WLAN').fontSize(30).padding({ left: 15 })
}
}.hideTitleBar(false).backgroundColor('#0c182431')
}.backgroundColor(this.isActiveWLAN ? '#ccc' : '#fff')
.borderRadius(24)
.onStateChange((isActivated: boolean) => {
this.isActiveWLAN = isActivated
})
NavRouter组件的子组件,用于显示导航内容区---NavDestination
图案密码锁组件---PatternLock
使用:PatternLock(controller?: PatternLockController)
例如: private patternLockController: PatternLockController = new PatternLockController()
PatternLock(this.patternLockController)
.sideLength(200)
.circleRadius(9)
.pathStrokeWidth(18)
.activeColor('#B0C4DE')
.selectedColor('#228B22')
.pathColor('#90EE90')
.backgroundColor('#F5F5F5')
.autoReset(true)
.onPatternComplete((input: Array<number>) => {
// 输入的密码长度小于5时,提示重新输入
if (input === null || input === undefined || input.length < 5) {
this.message = 'The password length needs to be greater than 5, please enter again.'
return
}
// 判断密码长度是否大于0
if (this.passwords.length > 0) {
// 判断两次输入的密码是否相同,相同则提示密码设置成功,否则提示重新输入
if (this.passwords.toString() === input.toString()) {
this.passwords = input
this.message = 'Set password successfully: ' + this.passwords.toString()
} else {
this.message = 'Inconsistent passwords, please enter again.'
}
} else {
// 提示第二次输入密码
this.passwords = input
this.message = "Please enter again."
}
})
进度条组件---Progress
使用:Progress(options: {value: number, total?: number, type?: ProgressType})
例如:
Progress({ value: 10, type: ProgressType.ScaleRing }).width(100)
Progress({ value: 20, total: 150, type: ProgressType.ScaleRing })
.color(Color.Grey).value(50).width(100)
.style({ strokeWidth: 15, scaleCount: 15, scaleWidth: 5 })
显示单个二维码的组件---QRCode
使用:QRCode(value: string)
例如:QRCode(this.value).color(0xF7CE00).width(200).height(200)
星星评分的组件---Rating
使用:Rating(options?: { rating: number, indicator?: boolean })
例如:Rating({ rating: this.rating, indicator: false })
.stars(5)
.stepSize(0.5)
.margin({ top: 24 })
.onChange((value: number) => {
this.rating = value
})
富文本组件,解析并显示HTML格式文本---RichText
使用:RichText(content:string)
例如:RichText(this.data)
.onStart(() => {
console.info('RichText onStart');
})
.onComplete(() => {
console.info('RichText onComplete');
})
.width(500)
.height(400)
.backgroundColor(0XBDDB69)
滚动条组件---ScrollBar
使用:ScrollBar(value: { scroller: Scroller, direction?: ScrollBarDirection, state?: BarState })
例如:ScrollBar({ scroller: this.scroller, direction: ScrollBarDirection.Vertical,state: BarState.Auto }) {
Text()
.width(20)
.height(100)
.borderRadius(10)
.backgroundColor('#C0C0C0')
}.width(20).backgroundColor('#ededed')
滑动条组件---Slider(用于快速调节设置值,如音量调节、亮度调节等应用场景)
使用:Slider(options?: {value?: number, min?: number, max?: number, step?: number, style?: SliderStyle, direction?: Axis, reverse?: boolean})
例如:Slider({
value: this.vInSetValueOne,
style: SliderStyle.InSet,
direction: Axis.Vertical,
reverse: true // 竖向的Slider默认是上端是min值,下端是max值,因此想要从下往上滑动,需要设置reverse为true
})
.showTips(true)
.onChange((value: number, mode: SliderChangeMode) => {
this.vInSetValueOne = value
console.info('value:' + value + 'mode:' + mode.toString())
})
搜索框组件---Search
使用:Search(options?: { value?: string, placeholder?: string, icon?: string, controller?: SearchController })
例如:Search({ value: this.changeValue, placeholder: 'Type to search...', controller: this.controller })
.searchButton('SEARCH')
.width(400)
.height(40)
.backgroundColor('#F5F5F5')
.placeholderColor(Color.Grey)
.placeholderFont({ size: 14, weight: 400 })
.textFont({ size: 14, weight: 400 })
.onSubmit((value: string) => {
this.submitValue = value
})
.onChange((value: string) => {
this.changeValue = value
})
.margin(20)
下拉选择菜单---Select
使用:Select(options: Array<SelectOption>)
例如:Select([{ value: 'aaa', icon: "/common/public_icon.svg" },
{ value: 'bbb', icon: "/common/public_icon.svg" },
{ value: 'ccc', icon: "/common/public_icon.svg" },
{ value: 'ddd', icon: "/common/public_icon.svg" }])
.selected(2)
.value('TTTTT')
.font({ size: 16, weight: 500 })
.fontColor('#182431')
.selectedOptionFont({ size: 16, weight: 400 })
.optionFont({ size: 16, weight: 400 })
.onSelect((index: number) => {
console.info('Select:' + index)
})
显示一段文本的组件----Text
使用:Text(content?: string | Resource)
例如: Text('This is set textOverflow to Ellipsis text content This is set textOverflow to Ellipsis text content.'.split('')
.join('\u200B'))
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
.fontSize(12)
.border({ width: 1 })
.padding(10)
显示行内文本的组件---Span
使用:Span(value: string | Resource)
例如:Span('I am Lower-span').fontSize(12)
.textCase(TextCase.LowerCase)
.decoration({ type: TextDecorationType.None })
多行文本输入框组件---TextArea(文本内容超过组件宽度时会自动换行显示)
使用:TextArea(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextAreaController})
例如:TextArea({
placeholder: 'The text area can hold an unlimited amount of text. input your word...',
controller: this.controller
})
.placeholderFont({ size: 16, weight: 400 })
.width(336)
.height(56)
.margin(20)
.fontSize(16)
.fontColor('#182431')
.backgroundColor('#FFFFFF')
.onChange((value: string) => {
this.text = value
})
时间显示器---TextClock
使用:TextClock(options?: { timeZoneOffset?: number, controller?: TextClockController })
例如: // 以12小时制显示东八区的系统时间,精确到秒。
TextClock({ timeZoneOffset: -8, controller: this.controller })
.format('hms')
.onDateChange((value: number) => {
this.accumulateTime = value
})
.margin(20)
.fontSize(30)
单行文本输入框组件---TextInput
使用:TextInput(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextInputController})
例如:TextInput({ text: this.text, placeholder: 'input your word...', controller: this.controller })
.placeholderColor(Color.Grey)
.placeholderFont({ size: 14, weight: 400 })
.caretColor(Color.Blue)
.width(400)
.height(40)
.margin(20)
.fontSize(14)
.fontColor(Color.Black)
.inputFilter('[a-z]', (e) => {
console.log(JSON.stringify(e))
})
.onChange((value: string) => {
this.text = value
})
滑动选择文本内容的组件---TextPicker(滚筒选择器)
使用:TextPicker(options?: {range: string[]|Resource, selected?: number, value?: string})
例如: TextPicker({ range: this.fruits, selected: this.select })
.onChange((value: string, index: number) => {
console.info('Picker item changed, value: ' + value + ', index: ' + index)
})
文本显示计时信息并控制其计时器状态的组件---TextTimer(倒计时)
使用:TextTimer(options?: { isCountDown?: boolean, count?: number, controller?: TextTimerController })
例如:TextTimer({ isCountDown: true, count: 30000, controller: this.textTimerController })
.format(this.format)
.fontColor(Color.Black)
.fontSize(50)
.onTimer((utc: number, elapsedTime: number) => {
console.info('textTimer notCountDown utc is:' + utc + ', elapsedTime: ' + elapsedTime)
})
时间选择器---TimePicker
使用:TimePicker(options?: {selected?: Date})
例如:TimePicker({
selected: this.selectedTime,
})
.useMilitaryTime(this.isMilitaryTime)
.onChange((value: TimePickerResult) => {
this.selectedTime.setHours(value.hour, value.minute)
console.info('select current date is: ' + JSON.stringify(value))
})
步骤导航器组件---Stepper(类似于引导页面)
使用:Stepper(value?: { index?: number })
例如:Stepper({
index: this.currentIndex
}) {
// 第一个步骤页
StepperItem() {
Column() {
Text('Page One')
.itemTextStyle()
Button('change status:' + this.firstState)
.backgroundColor('#007dFF')
.onClick(() => {
this.firstState = this.firstState === ItemState.Skip ? ItemState.Normal : ItemState.Skip
})
}.itemStyle()
}
.nextLabel('Next')
.status(this.firstState)
// 第二个步骤页
StepperItem() {
Column() {
Text('Page Two')
.itemTextStyle()
Button('change status:' + this.secondState)
.backgroundColor('#007dFF')
.onClick(() => {
this.secondState = this.secondState === ItemState.Disabled ? ItemState.Normal : ItemState.Disabled
})
}.itemStyle()
}
.nextLabel('Next')
.prevLabel('Previous')
.status(this.secondState)
// 第三个步骤页
StepperItem() {
Column() {
Text('Page Three')
.itemTextStyle()
Button('change status:' + this.thirdState)
.backgroundColor('#007dFF')
.onClick(() => {
this.thirdState = this.thirdState === ItemState.Waiting ? ItemState.Normal : ItemState.Waiting
})
}.itemStyle()
}
.status(this.thirdState)
// 第四个步骤页
StepperItem() {
Column() {
Text('Page Four')
.itemTextStyle()
}.itemStyle()
}
}
.backgroundColor('#F1F3F5')
.onFinish(() => {
// 此处可处理点击最后一页的Finish时的逻辑,例如路由跳转等
console.info('onFinish')
})
.onSkip(() => {
// 此处可处理点击跳过时的逻辑,例如动态修改Stepper的index值使其跳转到某一步骤页等
console.info('onSkip')
})
.onChange((prevIndex: number, index: number) => {
this.currentIndex = index
})
Stepper组件的页面子组件---StepperItem
使用:StepperItem()
具有网页显示能力的Web组件---Web
使用:Web(options: { src: ResourceStr, controller: WebviewController | WebController})(访问在线网页时需添加网络权限:ohos.permission.INTERNET)
例如:Web({ src: 'www.example.com', controller: this.controller })
用于EGL/OpenGLES和媒体数据写入---XComponent
使用:XComponent(value: {id: string, type: string, libraryname?: string, controller?: XComponentController})
例如: XComponent({
id: 'xcomponent',
type: 'surface',
controller: this.xcomponentController
})
.onLoad(() => {
this.xcomponentController.setXComponentSurfaceSize({surfaceWidth:1920,surfaceHeight:1080});
this.surfaceId = this.xcomponentController.getXComponentSurfaceId()
})
.width('640px')
.height('480px')
}
容器组件
附加在单个组件上用于信息标记的容器组件---Badge(类似于数量标记或者有更新标记)
使用:Badge(value: {count: number, position?: BadgePosition, maxCount?: number, style: BadgeStyle})(数字标记组件)
Badge(value: {value: string, position?: BadgePosition, style: BadgeStyle})(字符串创建标记组件)
例如:
Badge({
value: 'New',
position: BadgePosition.Right,
style: { badgeSize: 16, badgeColor: '#FA2A2D' }
}) {
Text('list2').width(27).height(19).fontSize(14).fontColor('#182431')
}.width(49.5).height(19)
.margin({ left: 12 })
Badge({
value: '',
style: { badgeSize: 6, badgeColor: '#FA2A2D' }
}) {
Image('/common/public_icon_off.svg')
.width(24)
.height(24)
}
.width(24)
.height(24)
.margin({ bottom: 4 })
垂直方向布局的容器---Column
使用:Column(value?: {space?: string | number})
例如:Column({ space: 5 }) {
Column().width('100%').height(30).backgroundColor(0xAFEEEE)
Column().width('100%').height(30).backgroundColor(0x00FFFF)
}.width('90%').height(100).border({ width: 1 })
子组件纵向布局,并在每个子组件之间插入一根横向的分割线---ColumnSplit
使用:ColumnSplit()
例如:Column(){
Text('The secant line can be dragged').fontSize(9).fontColor(0xCCCCCC).width('90%')
ColumnSplit() {
Text('1').width('100%').height(50).backgroundColor(0xF5DEB3).textAlign(TextAlign.Center)
Text('2').width('100%').height(50).backgroundColor(0xD2B48C).textAlign(TextAlign.Center)
Text('3').width('100%').height(50).backgroundColor(0xF5DEB3).textAlign(TextAlign.Center)
Text('4').width('100%').height(50).backgroundColor(0xD2B48C).textAlign(TextAlign.Center)
Text('5').width('100%').height(50).backgroundColor(0xF5DEB3).textAlign(TextAlign.Center)
}
.borderWidth(1)
.resizeable(true) // 可拖动
.width('90%').height('60%')
}.width('100%')
沿水平方向布局容器---Row
使用:Row(value?:{space?: number | string })
例如: Row() {
Row().width('30%').height(50).backgroundColor(0xAFEEEE)
Row().width('30%').height(50).backgroundColor(0x00FFFF)
}.width('90%').alignItems(VerticalAlign.Bottom).height('15%').border({ width: 1 })
子组件横向布局,并在每个子组件之间插入一根纵向的分割线---RowSplit
使用:RowSplit()
例如:RowSplit() {
Text('1').width('10%').height(100).backgroundColor(0xF5DEB3).textAlign(TextAlign.Center)
Text('2').width('10%').height(100).backgroundColor(0xD2B48C).textAlign(TextAlign.Center)
Text('3').width('10%').height(100).backgroundColor(0xF5DEB3).textAlign(TextAlign.Center)
Text('4').width('10%').height(100).backgroundColor(0xD2B48C).textAlign(TextAlign.Center)
Text('5').width('10%').height(100).backgroundColor(0xF5DEB3).textAlign(TextAlign.Center)
}
.resizeable(true) // 可拖动
.width('90%').height(100)
计数器---Counter(物品数量加减)
使用:Counter()
例如:Counter() {
Text(this.value.toString())
}.margin(100)
.onInc(() => {
this.value++
})
.onDec(() => {
this.value--
})
弹性方式布局---Flex
使用:Flex(value?: { direction?: FlexDirection, wrap?: FlexWrap, justifyContent?: FlexAlign, alignItems?: ItemAlign, alignContent?: FlexAlign })
例如:Flex({ direction: FlexDirection.Column }) { // 子组件在容器主轴上列布局
Text('1').width('100%').height(40).backgroundColor(0xF5DEB3)
Text('2').width('100%').height(40).backgroundColor(0xD2B48C)
Text('3').width('100%').height(40).backgroundColor(0xF5DEB3)
Text('4').width('100%').height(40).backgroundColor(0xD2B48C)
}
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)
}
展示瀑布流具体item---FlowItem
使用:FlowItem()
栅格容器组件---GridRow(不可滚动宫格网格)
使用:GridRow(option?: {columns?: number | GridRowColumnOption, gutter?: Length | GutterOption, breakpoints?: BreakPoints, direction?: GridRowDirection})
例如:GridRow({
columns: 5,
gutter: { x: 5, y: 10 },
breakpoints: { value: ["400vp", "600vp", "800vp"],
reference: BreakpointsReference.WindowSize },
direction: GridRowDirection.Row
}) {
ForEach(this.bgColors, (color) => {
GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 } }) {
Row().width("100%").height("20vp")
}.borderColor(color).borderWidth(2)
})
}.width("100%").height("100%")
.onBreakpointChange((breakpoint) => {
this.currentBp = breakpoint
})
栅格子组件--- GridCol
使用:GridCol(option?:{span?: number | GridColColumnOption, offset?: number | GridColColumnOption, order?: number | GridColColumnOption})
网格容器---Grid(可滚动宫格网格)
使用:Grid(scroller?: Scroller)
例如:Grid() {
ForEach(this.Number, (day: string) => {
ForEach(this.Number, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
}, day => day)
}, day => day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
网格容器中单项内容容器---GridItem
使用:GridItem()
例如:Grid() {
GridItem() {
Text('4')
.fontSize(16)
.backgroundColor(0xFAEEE0)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}.rowStart(1).rowEnd(2).columnStart(1).columnEnd(2) // 同时设置合理的行列号
ForEach(this.numbers, (item) => {
GridItem() {
Text(item)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
}, item => item)
GridItem() {
Text('5')
.fontSize(16)
.backgroundColor(0xDBD0C0)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}.columnStart(1).columnEnd(4) // 只设置列号,不会从第1列开始布局
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr 1fr')
.width('90%').height(300)
列表包含一系列相同宽度的列表项---List
使用:List(value?:{space?: number | string, initialIndex?: number, scroller?: Scroller})
例如:List({ space: 20, initialIndex: 0 }) {
ForEach(this.arr, (item) => {
ListItem() {
Text('' + item)
.width('100%').height(100).fontSize(16)
.textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
}
}, item => item)
}
.listDirection(Axis.Vertical) // 排列方向
.divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
.edgeEffect(EdgeEffect.Spring) // 滑动到边缘无效果
.onScrollIndex((firstIndex: number, lastIndex: number) => {
console.info('first' + firstIndex)
console.info('last' + lastIndex)
})
列表具体item---ListItem
使用:ListItem(value?: string)
例如:List({ space: 20, initialIndex: 0 }) {
ForEach(this.arr, (item) => {
ListItem() {
Text('' + item)
.width('100%').height(100).fontSize(16)
.textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
}
}, item => item)
}.width('90%')
List({space:10}) {
ListItem() {
Text(this.message)
.width('100%')
.height(100)
.fontSize(16)
.textAlign(TextAlign.Center)
.borderRadius(10)
.backgroundColor(0xFFFFFF)
}
.swipeAction({ end:this.itemEnd})
ListItem() {
Text(this.message)
.width('100%')
.height(100)
.fontSize(16)
.textAlign(TextAlign.Center)
.borderRadius(10)
.backgroundColor(0xFFFFFF)
}
.swipeAction({ start:this.itemEnd})
}
列表item分组---ListItemGroup(吸顶滑动二级列表)
使用:ListItemGroup(options?: {header?: CustomBuilder, footer?: CustomBuilder, space?: number | string})
例如:List({ space: 20 }) {
ForEach(this.timetable, (item) => {
ListItemGroup({ header:this.itemHead(item.title), footer:this.itemFoot(item.projects.length) }) {
ForEach(item.projects, (project) => {
ListItem() {
Text(project)
.width("100%").height(100).fontSize(20)
.textAlign(TextAlign.Center).backgroundColor(0xFFFFFF)
}
}, item => item)
}
.borderRadius(20)
.divider({ strokeWidth: 1, color: Color.Blue }) // 每行之间的分界线
})
}
路由容器组件,提供路由跳转能力---Navigator
使用:Navigator(value?: {target: string, type?: NavigationType})
例如:Navigator({ target: 'pages/container/navigator/Detail', type: NavigationType.Push }) {
Text('Go to ' + this.Text['name'] + ' page')
.width('100%').textAlign(TextAlign.Center)
}.params({ text: this.Text }) // 传参数到Detail页面
Navigator() {
Text('Back to previous page').width('100%').textAlign(TextAlign.Center)
}.active(this.active)
.onClick(() => {
this.active = true
})
Navigator({ target: 'pages/container/navigator/Back', type: NavigationType.Push }) {
Text('Go to back page').width('100%').height(20)
}
可滑动面板---Panel(底部弹窗,分大中小)
使用:Panel(show: boolean)
例如:Panel(this.show) { // 展示日程
Column() {
Text('Today Calendar')
Divider()
Text('1. afternoon 4:00 The project meeting')
}
}
.type(PanelType.Foldable).mode(PanelMode.Half)
.dragBar(true) // 默认开启
.halfHeight(500) // 默认一半
.onChange((width: number, height: number, mode: PanelMode) => {
console.info(`width:${width},height:${height},mode:${mode}`)
})
下拉操作并显示刷新动效---Refresh
使用:Refresh(value: { refreshing: boolean, offset?: number | string , friction?: number | string })
例如:Refresh({ refreshing: $$this.isRefreshing, offset: 120, friction: 100 }) {
Text('Pull Down and refresh: ' + this.counter)
.fontSize(30)
.margin(10)
}
.onStateChange((refreshStatus: RefreshStatus) => {
console.info('Refresh onStatueChange state is ' + refreshStatus)
})
.onRefreshing(() => {
setTimeout(() => {
this.counter++
this.isRefreshing = false
}, 1000)
console.log('onRefreshing test')
})
可滚动的容器组件---Scroll
使用:Scroll(scroller?: Scroller)
例如:Scroll(this.scrollerForScroll) {
Column() {
Text("Scroll Area")
.width("100%").height("40%").backgroundColor(0X330000FF)
.fontSize(16).textAlign(TextAlign.Center)
.onClick(() => {
this.scrollerForList.scrollToIndex(5)
})
List({ space: 20, scroller: this.scrollerForList }) {
ForEach(this.arr, (item) => {
ListItem() {
Text("ListItem" + item)
.width("100%").height("100%").borderRadius(15)
.fontSize(16).textAlign(TextAlign.Center).backgroundColor(Color.White)
}.width("100%").height(100)
}, item => item)
}
.width("100%")
.height("50%")
.edgeEffect(EdgeEffect.None)
.onReachStart(() => {
this.listPosition = 0
})
.onReachEnd(() => {
this.listPosition = 2
})
.onScrollFrameBegin((offset: number) => {
if ((this.listPosition == 0 && offset <= 0) || (this.listPosition == 2 && offset >= 0)) {
this.scrollerForScroll.scrollBy(0, offset)
return { offsetRemain: 0 }
}
this.listPosition = 1
return { offsetRemain: offset };
})
Text("Scroll Area")
.width("100%").height("40%").backgroundColor(0X330000FF)
.fontSize(16).textAlign(TextAlign.Center)
}
}
相对布局组件---RelativeContainer
使用:RelativeContainer()
例如:RelativeContainer() {
Row().width(100).height(100)
.backgroundColor("#FF3333")
.alignRules({
top: {anchor: "__container__", align: VerticalAlign.Top},
left: {anchor: "__container__", align: HorizontalAlign.Start}
})
.id("row1")
Row().width(100).height(100)
.backgroundColor("#FFCC00")
.alignRules({
top: {anchor: "__container__", align: VerticalAlign.Top},
right: {anchor: "__container__", align: HorizontalAlign.End}
})
.id("row2")
Row().height(100)
.backgroundColor("#FF6633")
.alignRules({
top: {anchor: "row1", align: VerticalAlign.Bottom},
left: {anchor: "row1", align: HorizontalAlign.End},
right: {anchor: "row2", align: HorizontalAlign.Start}
})
.id("row3")
Row()
.backgroundColor("#FF9966")
.alignRules({
top: {anchor: "row3", align: VerticalAlign.Bottom},
bottom: {anchor: "__container__", align: VerticalAlign.Bottom},
left: {anchor: "__container__", align: HorizontalAlign.Start},
right: {anchor: "row1", align: HorizontalAlign.End}
})
.id("row4")
Row()
.backgroundColor("#FF66FF")
.alignRules({
top: {anchor: "row3", align: VerticalAlign.Bottom},
bottom: {anchor: "__container__", align: VerticalAlign.Bottom},
left: {anchor: "row2", align: HorizontalAlign.Start},
right: {anchor: "__container__", align: HorizontalAlign.End}
})
.id("row5")
}
.width(300).height(300)
.margin({left: 100})
.border({width:2, color: "#6699FF"})
侧边栏可以显示和隐藏的侧边栏容器---SideBarContainer
使用:SideBarContainer( type?: SideBarContainerType )
例如:SideBarContainer(SideBarContainerType.Embed) {
Column() {
ForEach(this.arr, (item, index) => {
Column({ space: 5 }) {
Image(this.current === item ? this.selectedIcon : this.normalIcon).width(64).height(64)
Text("Index0" + item)
.fontSize(25)
.fontColor(this.current === item ? '#0A59F7' : '#999')
.fontFamily('source-sans-pro,cursive,sans-serif')
}
.onClick(() => {
this.current = item
})
}, item => item)
}.width('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.backgroundColor('#19000000')
Column() {
Text('SideBarContainer content text1').fontSize(25)
Text('SideBarContainer content text2').fontSize(25)
}
.margin({ top: 50, left: 20, right: 30 })
}
.controlButton({
icons: {
hidden: $r('app.media.drawer'),
shown: $r('app.media.drawer'),
switching: $r('app.media.drawer')
}
})
.sideBarWidth(150)
.minSideBarWidth(50)
.maxSideBarWidth(300)
.onChange((value: boolean) => {
console.info('status:' + value)
})
堆叠容器---Stack
使用:Stack(value?: { alignContent?: Alignment })
例如:Stack({ alignContent: Alignment.Bottom }) {
Text('First child, show in bottom').width('90%').height('100%').backgroundColor(0xd2cab3).align(Alignment.Top)
Text('Second child, show in top').width('70%').height('60%').backgroundColor(0xc1cbac).align(Alignment.Top)
}.width('100%').height(150).margin({ top: 5 })
滑块视图容器---Swiper(轮播图容器)
使用:Swiper(controller?: SwiperController)
例如:Swiper(this.swiperController) {
LazyForEach(this.data, (item: string) => {
Text(item).width('90%').height(160).backgroundColor(0xAFEEEE).textAlign(TextAlign.Center).fontSize(30)
}, item => item)
}
.cachedCount(2)
.index(1)
.autoPlay(true)
.interval(4000)
.indicator(true)
.loop(true)
.duration(1000)
.itemSpace(0)
.curve(Curve.Linear)
.onChange((index: number) => {
console.info(index.toString())
})
页签进行内容视图切换的容器组件---Tabs
使用:Tabs(value?: {barPosition?: BarPosition, index?: number, controller?: TabsController})
例如: Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {
TabContent() {
Column().width('100%').height('100%').backgroundColor('#00CB87')
}.tabBar(this.TabBuilder(0, 'green'))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#007DFF')
}.tabBar(this.TabBuilder(1, 'blue'))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#FFBF00')
}.tabBar(this.TabBuilder(2, 'yellow'))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#E67C92')
}.tabBar(this.TabBuilder(3, 'pink'))
}
.vertical(false)
.barMode(BarMode.Fixed)
.barWidth(360)
.barHeight(56)
.animationDuration(400)
.onChange((index: number) => {
this.currentIndex = index
})
.width(360)
.height(296)
.margin({ top: 52 })
.backgroundColor('#F1F3F5')
对应一个切换页签的内容视图---TabContent
使用:TabContent()
例如:TabContent() {
Column() {
Text('Tab1')
.fontSize(36)
.fontColor('#182431')
.fontWeight(500)
.opacity(0.4)
.margin({ top: 30, bottom: 56.5 })
Divider()
.strokeWidth(0.5)
.color('#182431')
.opacity(0.05)
}.width('100%')
}.tabBar(this.TabBuilder(0))
瀑布流容器---WaterFlow
使用:WaterFlow(options?: {footer?: CustomBuilder, scroller?: Scroller})
例如:WaterFlow({ footer: this.itemFoot.bind(this), scroller: this.scroller }) {
LazyForEach(this.datasource, (item: number) => {
FlowItem() {
Column() {
Text("N" + item).fontSize(12).height('16')
Image('res/waterFlowTest(' + item % 5 + ').jpg')
.objectFit(ImageFit.Fill)
}
}
.width(this.itemWidthArray[item])
.height(this.itemHeightArray[item])
.backgroundColor(this.colors[item % 5])
}, item => item)
}
.columnsTemplate("1fr 1fr 1fr 1fr")
.itemConstraintSize({
minWidth: 0,
maxWidth: '100%',
minHeight: 0,
maxHeight: '100%'
})
.columnsGap(10)
.rowsGap(5)
.onReachStart(() => {
console.info("onReachStart")
})
.onReachEnd(() => {
console.info("onReachEnd")
})
.backgroundColor(0xFAEEE0)
.width('100%')
.height('80%')
.layoutDirection(FlexDirection.Column)
媒体组件
播放视频文件并控制其播放状态的组件---Video
使用:Video(value: {src?: string | Resource, currentProgressRate?: number | string | PlaybackSpeed, previewUri?: string | PixelMap | Resource, controller?: VideoController})
例如:Video({
src: this.videoSrc,
previewUri: this.previewUri,
currentProgressRate: this.curRate,
controller: this.controller
}).width('100%').height(600)
.autoPlay(this.isAutoPlay)
.controls(this.showControls)
.onStart(() => {
console.info('onStart')
})
.onPause(() => {
console.info('onPause')
})
.onFinish(() => {
console.info('onFinish')
})
.onError(() => {
console.info('onError')
})
.onPrepared((e) => {
console.info('onPrepared is ' + e.duration)
})
.onSeeking((e) => {
console.info('onSeeking is ' + e.time)
})
.onSeeked((e) => {
console.info('onSeeked is ' + e.time)
})
.onUpdate((e) => {
console.info('onUpdate is ' + e.time)
})
绘制组件(画板、自定义组件相关)
绘制圆形的组件---Circle
使用:Circle(options?: {width?: string | number, height?: string | number})
例如:// 绘制一个直径为150的圆
Circle({ width: 150, height: 150 })
// 绘制一个直径为150、线条为红色虚线的圆环(宽高设置不一致时以短边为直径)
Circle()
.width(150)
.height(200)
.fillOpacity(0)
.strokeWidth(3)
.stroke(Color.Red)
.strokeDashArray([1, 2])
椭圆绘制组件---Ellipse
使用:Ellipse(options?: {width?: string | number, height?: string | number})
例如:// 绘制一个 150 * 80 的椭圆
Ellipse({ width: 150, height: 80 })
// 绘制一个 150 * 100 、线条为蓝色的椭圆环
Ellipse()
.width(150)
.height(100)
.fillOpacity(0)
.stroke(Color.Blue)
.strokeWidth(3)
直线绘制组件---Line
使用:Line(value?: {width?: string | number, height?: string | number})
例如:Line()
.width(200)
.height(150)
.startPoint([50, 50])
.endPoint([150, 150])
.strokeWidth(5)
.stroke(Color.Orange)
.strokeOpacity(0.5)
.backgroundColor('#F5F5F5')
折线绘制组件---Polyline
使用:Polyline(value?: {width?: string | number, height?: string | number})
例如:// 在 100 * 100 的矩形框中绘制一段折线,起点(20, 0),经过(0,100),到达终点(100, 90)
Polyline()
.width(100)
.height(100)
.fillOpacity(0)
.stroke(Color.Red)
.strokeWidth(8)
.points([[20, 0], [0, 100], [100, 90]])
// 设置折线拐角处为圆弧
.strokeLineJoin(LineJoinStyle.Round)
// 设置折线两端为半圆
.strokeLineCap(LineCapStyle.Round)
多边形绘制组件---Polygon
使用:Polygon(value?: {width?: string | number, height?: string | number})
例如: // 在 100 * 100 的矩形框中绘制一个五边形,起点(50, 0),依次经过(0, 50)、(20, 100)和(80, 100),终点(100, 50)
Polygon().width(100).height(100)
.points([[50, 0], [0, 50], [20, 100], [80, 100], [100, 50]])
.fill(Color.Red)
.fillOpacity(0.6)
路径绘制组件---Path(根据绘制路径生成封闭的自定义形状)
使用:Path(value?: { width?: number | string; height?: number | string; commands?: string })
例如:// 绘制弧线图形
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
Path()
.commands("M0 300 S100 0 240 300 Z")
.fillOpacity(0)
.stroke(Color.Black)
.strokeWidth(3)
Path()
.commands('M0 150 C0 100 140 0 200 150 L100 300 Z')
.fillOpacity(0)
.stroke(Color.Black)
.strokeWidth(3)
Path()
.commands('M0 100 A30 20 20 0 0 200 100 Z')
.fillOpacity(0)
.stroke(Color.Black)
.strokeWidth(3)
}.width('95%')
矩形绘制组件---Rect
使用:Rect(value?: {width?: string | number,height?: string | number,radius?: string | number | Array<string | number>} |{width?: string | number,height?: string | number,radiusWidth?: string | number,radiusHeight?: string | number})
例如:// 绘制90% * 80的矩形, 圆角宽高分别为40、20
Rect({ width: '90%', height: 80 })
.radiusHeight(20)
.radiusWidth(40)
.fill(Color.Pink)
绘制组件的父组件---Shape
使用:Shape(value?: PixelMap)
例如:Shape() {
Rect().width(300).height(50)
Ellipse().width(300).height(50).offset({ x: 0, y: 60 })
Path().width(300).height(10).commands('M0 0 L900 0').offset({ x: 0, y: 120 })
}
.viewPort({ x: -2, y: -2, width: 304, height: 130 })
.fill(0x317AF7)
.stroke(Color.Black)
.strokeWidth(4)
.strokeDashArray([20])
.strokeDashOffset(10)
.strokeLineCap(LineCapStyle.Round)
.strokeLineJoin(LineJoinStyle.Round)
.antiAlias(true)
画布组件(自定义组件相关)
画布组件---Canvas
使用:Canvas(context?: CanvasRenderingContext2D)
例如: Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#ffff00')
.onReady(() => {
this.context.fillRect(0, 30, 100, 100)
})
Canvas组件绘制对象---CanvasRenderingContext2D
使用:https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-canvasrenderingcontext2d-0000001478181441-V3
例如:private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
渐变对象---CanvasGradient
使用:context.createLinearGradient(50, 0, 300, 100)
例如:var grad = this.context.createLinearGradient(50, 0, 300, 100)
存储canvas渲染的像素数据---ImageBitmap
使用:ImageBitmap(src: string)
例如:private img:ImageBitmap = new ImageBitmap("common/images/example.jpg")
this.context.drawImage(this.img,0,0,130,130)
或
以上且含
var imagedata = this.context.getImageData(50,50,130,130)
this.context.putImageData(imagedata,150,150)
离屏绘制---OffscreenCanvasRenderingContext2D
使用OffscreenCanvasRenderingContext2D在Canvas上进行离屏绘制,绘制对象可以是矩形、文本、图片等。离屏绘制是指将需要绘制的内容先绘制在缓存区,然后将其转换成图片,一次性绘制到canvas上,加快了绘制速度。
使用:OffscreenCanvasRenderingContext2D(width: number, height: number, settings: RenderingContextSettings)
使用:
struct LineWidthExample {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings)
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Canvas(this.context)
.width('100%')
.height('100%')
.backgroundColor('#ffff00')
.onReady(() =>{
this.offContext.lineWidth = 5
this.offContext.strokeRect(25, 25, 85, 105)
var image = this.offContext.transferToImageBitmap()
this.context.transferFromImageBitmap(image)
})
}
.width('100%')
.height('100%')
}
}
路径对象,支持通过对象的接口进行路径---Path2D
使用:addPath(path: path2D, transform?:Matrix2D): void
例如:this.path2Db.addPath(this.path2Da)