vlayout能够处理列表、网格和其他布局在同一个视图的复杂情况,使用者可以使用已设定好的容器布局组件,也可以在此基础上自定义容器布局组件。
BANNER_LAYOUT滑动容器布局组件
COLUMN_LAYOUT栏格容器布局组件
DEFAULT_LAYOUT默认容器布局组件
FIX_LAYOUT固定容器布局组件
FLOAT_LAYOUT浮动容器布局组件
GRID_LAYOUT复杂网格容器布局组件
LINEAR_LAYOUT列表容器布局组件
ONEN_LAYOUT一拖N容器布局组件
ONEN_EX_LAYOUT一拖N拓展容器布局组件
RANGEGRID_LAYOUT区域网格容器布局组件
SCROLL_FIX_LAYOUT滚动固定容器布局组件
SINGLE_LAYOUT通栏容器布局组件
STAGGEREDGRID_LAYOUT交错网格容器布局组件
STICKY_LAYOUT吸顶容器布局组件
跳转item项位置
参考安装教程 如何安装OpenHarmony npm包
安装命令如下:
npm install @ohos/vlayout --save
1.通过ArkTS实现的vlayout与源库存在部分使用差异,在此会根据不同的容器组件来详细介绍基于openHarmony ArkTS实现的vlayout自定义容器组件的使用说明;
2.使用vlayout自定义容器组件需要给定最基本的三大要素:要显示的vLayoutContent布局内容、vLayoutData数据源以及vLayoutAttribute容器属性;
3.vlayout提供14种自定义容器组件,使用步骤主要分为两步:①导入需要使用的对应容器组件;②创建对应的容器组件对象并提供需要显示的布局内容;
4.局限性:
①vlayout建议在previewer屏宽720,屏高1280,DPI为240下进行预览;
②ArkTS原生Grid组件在无rowsTemplate属性的时候表示Grid可以进行内部滑动,但一旦嵌套在List中并且List能开始滑动之后grid的内部滑动就失效了;即List-ListItem存在滑动事件的时候,Grid的滑动事件就失效了;所以Grid可内部滑动的条件为设置宫格高并且ListItem不能可滑动,想要不内部滑动的条件为不设置宫格高度;
③GRID_LAYOUT存在合并单元格的功能,由于合并单元格需要对每一个单元格进行操作,故只能在数据源当中加入colsSpan的key来进行合并单元格;
④其中FLOAT_LAYOUT,FIX_LAYOUT,SCROLL_FIX_LAYOUT以及STICKY_LAYOUT在使用时,父容器必须使用Stack堆叠容器进行加载;
⑤在以下使用示例当中,当父容器为Column表明根布局可以为Column或是List等其他已有的基础容器;
⑥父容器建议的搭配为:Stack+List+ListItem或Scroll+Column;使用固定布局们,需使用Stack+List+ListItem的组合;
⑦宽度和高度是可显式提供的布局容器(仅当单提供layoutHeight高度属性时,同时给定的左右外边距才能生效):BANNER_LAYOUT、SINGLE_LAYOUT、ONEN_LAYOUT、ONEN_EX_LAYOUT、FIX_LAYOUT、SCROLL_FIX_LAYOUT、STICKY_LAYOUT、FLOAT_LAYOUT;
⑧高度是计算出来的布局容器(个别无法显式提供高度,高度是由Builder内提供的组件计算出来的高度):GRID_LAYOUT、RANGEGRID_LAYOUT、STAGGEREDGRID_LAYOUT、LINEAR_LAYOUT、DEFAULT_LAYOUT、COLUMN_LAYOUT;其中前四个可以显式提供布局高度,当布局高度小于Builder内提供的组件的总高时,可以进行内部滑动;
⑨使用者同时提供aspectRatio属性以及Builder里组件的高度的情况下,会出现布局异常,解决方案为:Builder内的height给定值为'100%'或给定由我们布局传出来的高度;
⑩具体使用demo请参考开源库sample页面的实现;
1.在构建自定义容器组件时,必须给定以下属性
属性 | 是否必填 | 说明(不同布局组件存在不同的属性) |
---|---|---|
vLayoutContent | 是 | 布局,使用@Builder构建自定义页面 |
vLayoutData: any[] | 是 | 数据源 |
vLayoutAttribute: Attributes | 是 | 属性类型 |
2.vlayout通过声明的方式进行属性的设置,为了方便管理各个容器布局类的属性,以下为vLayoutAttribute属性类,均为非必填属性
export declare type GridAttributes = {
/*
* GridLayoutHelper
* RangeGridLayoutHelper
*/
range?: Array<number> //可显示的条目,默认值为[0,数据源长度]
spanCount?: number //列数,默认值为1
weights?: Array<number> //列占比集合:数组元素数值约分为占比,默认值为[100]
autoExpand?: boolean //余子项宽度自适应,当weights未定义时有效,且与colsSpan存在互斥关系,默认值为true
aspectRatio?: number //GridItem的单行纵横比,默认值为0
layoutHeight?: Length //Grid容器高度
bgColor?: ResourceColor //Grid容器背景颜色,默认值为透明
zIndex?: number //z序,默认值为0
gap?: number //行列间距,默认值为0
vGap?: number //行与行的间距,默认值为0
hGap?: number //列与列的间距,默认值为0
padding?: Length[] //内边距,默认值为[],优先级比单给内边距高
topPadding?: Length //上内边距,默认值为0
rightPadding?: Length //右内边距,默认值为0
bottomPadding?: Length //下内边距,默认值为0
leftPadding?: Length //左内边距,默认值为0
margin?: Length[] //外边距,默认值为[],优先级比单给外边距高
topMargin?: Length //上外边距,默认值为0
rightMargin?: Length //右外边距,默认值为0
bottomMargin?: Length //下外边距,默认值为0
leftMargin?: Length //左外边距,默认值为0
}
export declare type StaggeredGridAttributes = {
/*
* StaggeredGridLayoutHelper
*/
range?: Array<number> //可显示的条目,默认值为[0,数据源长度]
lanes?: number //列数,默认值为1
bgColor?: ResourceColor //容器背景颜色,默认值为透明
zIndex?: number //z序,默认值为0
gap?: number //行列间距,默认值为0
vGap?: number //行与行的间距,默认值为0
hGap?: number //列与列的间距,默认值为0
padding?: Length[] //内边距,默认值为[],优先级比单给内边距高
topPadding?: Length //上内边距,默认值为0
rightPadding?: Length //右内边距,默认值为0
bottomPadding?: Length //下内边距,默认值为0
leftPadding?: Length //左内边距,默认值为0
margin?: Length[] //外边距,默认值为[],优先级比单给外边距高
topMargin?: Length //上外边距,默认值为0
rightMargin?: Length //右外边距,默认值为0
bottomMargin?: Length //下外边距,默认值为0
leftMargin?: Length //左外边距,默认值为0
}
export declare type AbstractFullFillAttributes = {
/*
* SingleLayoutHelper
* ColumnLayoutHelper
* OnePlusNLayoutHelper
* OnePlusNLayoutHelperEx
*/
range?: Array<number> //可显示的条目,默认值为[0,数据源长度]
rowWeights?: Array<number> //行权重,默认值为[],仅OnePlusNLayoutHelper、OnePlusNLayoutHelperEx支持
colWeights?: Array<number> //列权重,默认值为[]
hasHeader?: boolean //第一个子项变成一行一列,默认值为false,仅OnePlusNLayoutHelper支持
hasFooter?: boolean //最后一个子项变成一行一列,默认值为false,仅OnePlusNLayoutHelper支持
layoutWidth?: Length //容器宽度
layoutHeight?: Length //容器高度
aspectRatio?: number //容器纵横比
bgColor?: ResourceColor //容器背景颜色,默认值为透明
zIndex?: number //z序,默认值为0
padding?: Length[] //内边距,默认值为[],优先级比单给内边距高
topPadding?: Length //上内边距,默认值为0
rightPadding?: Length //右内边距,默认值为0
bottomPadding?: Length //下内边距,默认值为0
leftPadding?: Length //左内边距,默认值为0
margin?: Length[] //外边距,默认值为[],优先级比单给外边距高
topMargin?: Length //上外边距,默认值为0
rightMargin?: Length //右外边距,默认值为0
bottomMargin?: Length //下外边距,默认值为0
leftMargin?: Length //左外边距,默认值为0
}
export declare type BannerAttributes = {
/*
* BannerLayoutHelper
*/
range?: Array<number> //可显示的条目,默认值为[0,数据源长度]
layoutWidth?: Length //容器宽度
layoutHeight?: Length //容器高度
aspectRatio?: number //容器纵横比
bgColor?: ResourceColor //容器背景颜色,默认值为透明
layoutIndex?: number //设置当前在容器中显示的子组件的索引值,默认值为0
layoutAutoPlay?: boolean //子组件是否自动播放,自动播放状态下,导航点不可操作,默认值为false
layoutInterval?: number //使用自动播放时播放的时间间隔,单位为毫秒,默认值为1000
layoutIndicator?: boolean //是否启用导航点指示器,默认值为false
layoutLoop?: boolean //是否开启循环,默认值为false
layoutDuration?: number //子组件切换的动画时长,单位为毫秒,默认值为400
layoutVertical?: boolean //是否为纵向滑动,默认值为false
layoutItemSpace?: number | string //设置子组件与子组件之间间隙,默认值为0
layoutEffectMode?: EdgeEffect //滑动效果,默认值为None
zIndex?: number //z序,默认值为0
padding?: Length[] //内边距,默认值为[],优先级比单给内边距高
topPadding?: Length //上内边距,默认值为0
rightPadding?: Length //右内边距,默认值为0
bottomPadding?: Length //下内边距,默认值为0
leftPadding?: Length //左内边距,默认值为0
margin?: Length[] //外边距,默认值为[],优先级比单给外边距高
topMargin?: Length //上外边距,默认值为0
rightMargin?: Length //右外边距,默认值为0
bottomMargin?: Length //下外边距,默认值为0
leftMargin?: Length //左外边距,默认值为0
}
export declare type LinearAttributes = {
/*
* LinearLayoutHelper
* DefaultLayoutHelper
*/
range?: Array<number> //可显示的条目,默认值为[0,数据源长度]
dividerHeight?: number | string //列表项垂直间距,默认值为0
layoutHeight?: Length //容器高度
aspectRatio?: number //ListItem的单行纵横比,默认值为0
bgColor?: ResourceColor //容器背景颜色,默认值为透明
zIndex?: number //z序,默认值为0
padding?: Length[] //内边距,默认值为[],优先级比单给内边距高
topPadding?: Length //上内边距,默认值为0
rightPadding?: Length //右内边距,默认值为0
bottomPadding?: Length //下内边距,默认值为0
leftPadding?: Length //左内边距,默认值为0
margin?: Length[] //外边距,默认值为[],优先级比单给外边距高
topMargin?: Length //上外边距,默认值为0
rightMargin?: Length //右外边距,默认值为0
bottomMargin?: Length //下外边距,默认值为0
leftMargin?: Length //左外边距,默认值为0
}
export enum AlignType {
TOP_LEFT = 0,
TOP_RIGHT = 1,
BOTTOM_LEFT = 2,
BOTTOM_RIGHT = 3
}
export declare type FixAreaAttributes = {
/*
* FixLayoutHelper
* ScrollFixLayoutHelper
* StickyLayoutHelper
* FloatLayoutHelper
*/
range?: Array<number> //可显示的条目,默认值为[0,数据源长度]
layoutWidth?: Length //容器宽度
layoutHeight?: Length //容器高度,当容器纵横比为0时有效
aspectRatio?: number //容器纵横比
bgColor?: ResourceColor //容器背景颜色,默认值为透明
xOffset?: Length //水平偏移量,默认值为0,只有StickyLayoutHelper不支持
yOffset?: Length //竖直偏移量,默认值为0,只有StickyLayoutHelper不支持
alignType?: AlignType //固定的位置,只有StickyLayoutHelper不支持,优先级比单给xy高,FloatLayoutHelper中与defaultLocation进行累加
sketchMeasure?: boolean //宽度占满屏幕,只有FixLayoutHelper, ScrollFixLayoutHelper支持
stickyStart?: boolean //true:吸顶,false:吸底,只有StickyLayoutHelper支持
defaultLocation?: number[] //默认位置,只有FloatLayoutHelper支持,优先级比单给xy高,与alignType进行累加
zIndex?: number //z序,默认值为0
padding?: Length[] //内边距,默认值为[],优先级比单给内边距高
topPadding?: Length //上内边距,默认值为0
rightPadding?: Length //右内边距,默认值为0
bottomPadding?: Length //下内边距,默认值为0
leftPadding?: Length //左内边距,默认值为0
margin?: Length[] //外边距,默认值为[],优先级比单给外边距高
topMargin?: Length //上外边距,默认值为0
rightMargin?: Length //右外边距,默认值为0
bottomMargin?: Length //下外边距,默认值为0
leftMargin?: Length //左外边距,默认值为0
}
1.导入GRID_LAYOUT容器
import { GRID_LAYOUT } from '@ohos/vlayout'
2.创建GRID_LAYOUT对象并提供需要显示的布局内容
@Builder gridLayoutContent(item, position, gridItemHeight) {
Text(`${item.layoutText}`)
.width('100%')
.height(200)
.backgroundColor(0x33EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontColor(0x999999)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.onClick(() => {
console.info('position = ' + position)
})
}
build() {
Column() {
GRID_LAYOUT({
vLayoutContent: (item, position, gridItemHeight) => {
this.gridLayoutContent(item, position, gridItemHeight)
},
vLayoutData: [
{ layoutText: 1 }, { layoutText: 2 }, { layoutText: 3 }, { layoutText: 4 },
{ layoutText: 5 }, { layoutText: 6 }, { layoutText: 7 }, { layoutText: 8 },
],
vLayoutAttribute: {
range: [0, 7],
spanCount: 3,
weights: [25, 25],
layoutHeight: 300,
bgColor: Color.Pink,
gap: 10,
padding: [10, 10, 10, 10],
margin: [10, 10, 10, 10],
}
})
}
}
1.导入RANGEGRID_LAYOUT容器
import { RANGEGRID_LAYOUT } from '@ohos/vlayout'
2.创建RANGEGRID_LAYOUT对象并提供需要显示的布局内容
@Builder rangeGridLayoutContent(item, position, gridItemHeight) {
Column() {
Text(`${item.layoutText}`)
.width('100%')
.height('100%')
.backgroundColor(0x22EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontColor('#999999')
.fontSize(25)
.fontWeight(FontWeight.Bold)
.maxLines(1)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position)
})
}
.backgroundColor(item.bgColor)
.padding(5)
.margin({
top: position == 4 || position == 5 || position == 8 || position == 9 ? 5 : 0,
right: position == 5 || position == 7 || position == 9 || position == 11 ? 10 : 0,
bottom: position == 6 || position == 7 || position == 10 || position == 11 ? 5 : 0,
left: position == 4 || position == 6 || position == 8 || position == 10 ? 10 : 0
})
}
build() {
Column() {
RANGEGRID_LAYOUT({
vLayoutContent: (item, position, gridItemHeight) => {
this.rangeGridLayoutContent(item, position, gridItemHeight)
},
vLayoutData: [
{ layoutText: 1 },
{ layoutText: 2 },
{ layoutText: 3 },
{ layoutText: 4 },
{ layoutText: 5, colsSpan: 2, bgColor: '#FF0000' },
{ layoutText: 6, colsSpan: 2, bgColor: '#FF0000' },
{ layoutText: 7, colsSpan: 2, bgColor: '#FF0000' },
{ layoutText: 8, colsSpan: 2, bgColor: '#FF0000' },
{ layoutText: 9, colsSpan: 2, bgColor: '#FFFF00' },
{ layoutText: 10, colsSpan: 2, bgColor: '#FFFF00' },
{ layoutText: 11, colsSpan: 2, bgColor: '#FFFF00' },
{ layoutText: 12, colsSpan: 2, bgColor: '#FFFF00' },
{ layoutText: 13 },
{ layoutText: 14 },
{ layoutText: 15 },
{ layoutText: 16 },
],
vLayoutAttribute: {
spanCount: 4,
weights: [20, 26.6, 26.6, 26.6],
aspectRatio: 4,
bgColor: '#00FF00',
padding: [10, 10, 10, 10],
margin: [10, 10, 10, 10]
}
})
}
}
1.导入STAGGEREDGRID_LAYOUT容器
import { STAGGEREDGRID_LAYOUT } from '@ohos/vlayout'
2.创建STAGGEREDGRID_LAYOUT对象并提供需要显示的布局内容
@Builder staggeredGridLayoutContent(item, position) {
if (position % 2 == 0) {
Text(`${item.layoutText}`)
.width('100%')
.height(220)
.backgroundColor('#33EEEEEE')
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontColor('#999999')
.fontSize(25)
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position + ', item = ' + JSON.stringify(item))
})
} else {
Text(`${item.layoutText}`)
.width('100%')
.height(150)
.backgroundColor('#33EEEEEE')
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontColor('#999999')
.fontSize(25)
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position + ', item = ' + JSON.stringify(item))
})
}
}
build() {
Column() {
STAGGEREDGRID_LAYOUT({
vLayoutContent: (item, position) => {
this.staggeredGridLayoutContent(item, position)
},
vLayoutData: [
{ layoutText: 1 },
{ layoutText: 2 },
{ layoutText: 3 },
{ layoutText: 4 },
{ layoutText: 5 },
{ layoutText: 6 },
{ layoutText: 7 },
{ layoutText: 8 },
{ layoutText: 9 },
{ layoutText: 10 },
],
vLayoutAttribute: {
range: [0, 8],
lanes: 3,
gap: 10,
bgColor: Color.Pink,
padding: [10, 10, 10, 10],
margin: [10, 10, 10, 10],
},
vLayoutId: 'STAGGERED'
})
}
}
1.导入COLUMN_LAYOUT容器
import { COLUMN_LAYOUT } from '@ohos/vlayout'
2.创建COLUMN_LAYOUT对象并提供需要显示的布局内容
@Builder columnLayoutContent(item, position, layoutHeight) {
Text(`${item.layoutText}`)
.width('100%')
.height(100)
.backgroundColor(0x22EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontSize(25)
.fontColor('#999999')
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position)
})
}
build() {
Column() {
COLUMN_LAYOUT({
vLayoutContent: (item, position, layoutHeight) => {
this.columnLayoutContent(item, position, layoutHeight)
},
vLayoutData: [
{ layoutText: 1 },
{ layoutText: 2 },
{ layoutText: 3 },
{ layoutText: 4 },
{ layoutText: 5 },
],
vLayoutAttribute: {
bgColor: Color.Pink,
colWeights: [30, 20, 20],
padding: [10, 10, 10, 10],
margin: [10, 10, 10, 10],
}
})
}
}
1.导入SINGLE_LAYOUT容器
import { SINGLE_LAYOUT } from '@ohos/vlayout'
2.创建SINGLE_LAYOUT对象并提供需要显示的布局内容
@Builder singleLayoutContent(item, position) {
Text(`${item}`)
.width('100%')
.height('100%')
.backgroundColor(0x22EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontSize(25)
.fontColor('#999999')
.fontWeight(FontWeight.Bold)
.maxLines(1)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position)
})
}
build() {
Column() {
SINGLE_LAYOUT({
vLayoutContent: (item, position) => {
this.singleLayoutContent(item, position)
},
vLayoutData: ['SINGLE'],
vLayoutAttribute: {
layoutHeight: 70,
bgColor: Color.Blue,
topMargin: 5,
bottomMargin: 90,
}
})
}
}
1.导入ONEN_LAYOUT容器
import { ONEN_LAYOUT }from '@ohos/vlayout'
2.创建ONEN_LAYOUT对象并提供需要显示的布局内容
@Builder onenLayoutContent(item) {
Text(`${item}`)
.width('100%')
.height('100%')
.backgroundColor(0x22EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontSize(25)
.fontColor('#999999')
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('item = ' + JSON.stringify(item))
})
}
build() {
Column() {
ONEN_LAYOUT({
vLayoutContent: (item) => {
this.onenLayoutContent(item)
},
vLayoutData: [1, 2, 3, 4, 5],
vLayoutAttribute: {
rowWeights: [10, 20],
colWeights: [100, 20, 30, 40, 10],
hasHeader: true,
hasFooter: false,
layoutHeight: 200,
bgColor: Color.Pink,
padding: [5, 5, 5, 5],
margin: [5, 15, 5, 15],
}
})
}
}
1.导入ONEN_EX_LAYOUT容器
import { ONEN_EX_LAYOUT }from '@ohos/vlayout'
2.创建ONEN_EX_LAYOUT对象并提供需要显示的布局内容
@Builder onenExLayoutContent(item) {
Text(`${item}`)
.width('100%')
.height('100%')
.backgroundColor('#33EEEEEE')
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontColor('#999999')
.fontSize(25)
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('item = ' + JSON.stringify(item))
})
}
build() {
Column() {
ONEN_EX_LAYOUT({
vLayoutContent: (item) => {
this.onenExLayoutContent(item)
},
vLayoutData: [1, 2, 3, 4, 5, 6],
vLayoutAttribute: {
rowWeights: [10, 20],
colWeights: [40, 45, 15, 10, 30, 30],
layoutHeight: 200,
bgColor: Color.Pink,
padding: [5, 5, 5, 5],
margin: [5, 15, 5, 15],
}
})
}
}
1.导入BANNER_LAYOUT容器
import { BANNER_LAYOUT }from '@ohos/vlayout'
2.创建BANNER_LAYOUT对象并提供需要显示的布局内容
@Builder bannerLayoutContent(item, position) {
Text('Banner:' + item)
.width('100%')
.height('100%')
.backgroundColor(0x22EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontSize(20)
.fontColor('#999999')
.fontWeight(FontWeight.Bold)
.maxLines(1)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position)
})
}
build() {
Column() {
BANNER_LAYOUT({
vLayoutContent: (item, position) => {
this.bannerLayoutContent(item, position)
},
vLayoutData: [0, 1, 2, 3, 4, 5],
vLayoutAttribute: {
aspectRatio: 4,
bgColor: Color.Pink,
padding: [10, 10, 10, 10],
margin: [10, 0, 10, 0],
},
})
}
}
1.导入LINEAR_LAYOUT容器
import { LINEAR_LAYOUT }from '@ohos/vlayout'
2.创建LINEAR_LAYOUT对象并提供需要显示的布局内容
@Builder linearLayoutContent(item, position) {
Text(`${item}`)
.width('100%')
.height('100%')
.backgroundColor(0x22EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontSize(25)
.fontColor('#999999')
.fontWeight(FontWeight.Bold)
.maxLines(1)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position)
})
}
build() {
Column() {
LINEAR_LAYOUT({
vLayoutContent: (item, position) => {
this.linearLayoutContent(item, position)
},
vLayoutData: [0, 1, 2, 3, 4, 5, 6],
vLayoutAttribute: {
dividerHeight: 10,
aspectRatio: 4,
layoutHeight: 500,
bgColor: Color.Pink,
padding: [10, 10, 10, 10],
margin: [10, 10, 10, 10],
},
})
}
}
1.导入DEFAULT_LAYOUT容器
import { DEFAULT_LAYOUT }from '@ohos/vlayout'
2.创建DEFAULT_LAYOUT对象并提供需要显示的布局内容
@Builder defaultLayoutContent(item, position) {
Text(`${item}`)
.width('100%')
.height('100%')
.backgroundColor(position % 2 == 0 ? '#aa00ff00' : '#ccff00ff')
.border({ width: 0, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontColor(0x000000)
.fontSize(18)
.fontWeight(FontWeight.Normal)
.textAlign(TextAlign.Start)
.align(Alignment.TopStart)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position)
})
}
build() {
Column() {
DEFAULT_LAYOUT({
vLayoutContent: (item, position) => {
this.defaultLayoutContent(item, position)
},
vLayoutData: [0, 1, 2, 3, 4, 5],
vLayoutAttribute: {
dividerHeight: 5,
aspectRatio: 4,
margin: [5, 5, 5, 5],
}
})
}
}
1.导入FLOAT_LAYOUT容器
import { FLOAT_LAYOUT } from '@ohos/vlayout'
2.创建FLOAT_LAYOUT对象并提供需要显示的布局内容,由于浮动组件需要在父容器进行叠层显示,所以推荐使用Stack为根布局
enum AlignType {
TOP_LEFT = 0,
TOP_RIGHT = 1,
BOTTOM_LEFT = 2,
BOTTOM_RIGHT = 3
}
@Builder floatLayoutContent(item, position) {
Text(`${item}`)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
}
build() {
Stack() {
Text('TEXT')
FLOAT_LAYOUT({
vLayoutContent: (item, position) => {
this.floatLayoutContent(item, position)
},
vLayoutData: ['FLOAT'],
vLayoutAttribute: {
layoutWidth: 150,
layoutHeight: 150,
bgColor: Color.Pink,
defaultLocation: [-50, -150],
alignType: AlignType.BOTTOM_RIGHT,
}
})
}
}
1.导入FIX_LAYOUT容器
import { FIX_LAYOUT } from '@ohos/vlayout'
2.创建FIX_LAYOUT对象并提供需要显示的布局内容,由于固定组件需要在父容器进行叠层显示,所以推荐使用Stack为根布局
enum AlignType {
TOP_LEFT = 0,
TOP_RIGHT = 1,
BOTTOM_LEFT = 2,
BOTTOM_RIGHT = 3
}
@Builder fixLayoutContent(item, position) {
Text(`${item}`)
.width('100%')
.height('100%')
.backgroundColor(0x22EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontSize(25)
.fontColor('#999999')
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position)
})
}
build() {
Stack() {
Text('TEXT')
FIX_LAYOUT({
vLayoutContent: (item, position) => {
this.fixLayoutContent(item, position)
},
vLayoutData: ['FIX'],
vLayoutAttribute: {
layoutWidth: 100,
layoutHeight: 100,
sketchMeasure: false,
bgColor: Color.Pink,
alignType: AlignType.TOP_RIGHT,
}
})
}
}
1.导入SCROLL_FIX_LAYOUT容器
import { SCROLL_FIX_LAYOUT }from '@ohos/vlayout'
import { LINEAR_LAYOUT }from '@ohos/vlayout'
import { JumpBar }from '@ohos/vlayout'
2.创建SCROLL_FIX_LAYOUT对象并提供需要显示的布局内容,由于滑动固定组件需要在父容器进行叠层显示并且需要在父容器滑动至某一位置之后出现,所以推荐使用Stack为根布局,并且在父容器中进行实现该效果,且必须与JumpBar进行连用
enum AlignType {
TOP_LEFT = 0,
TOP_RIGHT = 1,
BOTTOM_LEFT = 2,
BOTTOM_RIGHT = 3
}
private vScroller: Scroller = new Scroller()
@State private scroller: any[] = [this.vScroller]
@State private textFirst: number = 0
@State private textExisting: number = 0
@State private textCreated: number = 0
@State private textCount: number = 0
@State private textOffset: number = 0
@State private textInput: number = 0
@State data: any[] = [
{ layoutData: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, //LINEAR_LAYOUT
{ layoutData: [0] }, //SCROLL_FIX_LAYOUT
]
@Builder linearLayoutContent(item, position) {
Text(`${item}`)
.width('100%')
.height('100%')
.backgroundColor(0x22EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontSize(25)
.fontColor('#999999')
.fontWeight(FontWeight.Bold)
.maxLines(1)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position)
})
}
@Builder scrollFixLayoutContent(item, position) {
Text(`${item}`)
.width('100%')
.height('100%')
.backgroundColor(0x22EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontSize(25)
.fontColor(0x999999)
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position)
})
}
build() {
Stack({ alignContent: Alignment.Bottom }) {
List({ scroller: this.vScroller }) {
ListItem() {
LINEAR_LAYOUT({
vLayoutContent: (item, position) => {
this.linearLayoutContent(item, position)
},
vLayoutData: this.data[0].layoutData,
vLayoutAttribute: {
aspectRatio: 4,
}
})
}
}
.edgeEffect(EdgeEffect.None)
.onScrollIndex((start: number, end: number) => {
//获取First
if (typeof this.data[start].layoutData[0] == 'number') {
this.textFirst = this.data[start].layoutData[0]
}
})
//SCROLL_FIX_LAYOUT滑动至某个位置出现的效果
if (this.textFirst >= 0) {
SCROLL_FIX_LAYOUT({
vLayoutContent: (item, position) => {
this.scrollFixLayoutContent(item, position)
},
vLayoutData: this.data[1].layoutData,
vLayoutAttribute: {
layoutWidth: 100,
layoutHeight: 100,
bgColor: Color.Pink,
alignType: AlignType.TOP_LEFT,
}
})
}
JumpBar({
textShow: true,
textFirst: $textFirst,
textExisting: $textExisting,
textCreated: $textCreated,
textCount: $textCount,
textOffset: $textOffset,
textInput: $textInput,
scroller: $scroller,
})
}
}
1.导入STICKY_LAYOUT容器
import { STICKY_LAYOUT } from '@ohos/vlayout'
import { LINEAR_LAYOUT } from '@ohos/vlayout'
2.创建STICKY_LAYOUT对象并提供需要显示的布局内容,由于吸顶组件需要在父容器进行叠层显示并且需要在父容器滑动至某一位置之后吸顶或吸底,所以推荐使用Stack加List-ListItem为根布局,并且在父容器中进行实现该效果
@Builder stickyLayoutContent(item, position) {
Text(`${item}`)
.width('100%')
.height('100%')
.backgroundColor(0x22EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontSize(25)
.fontColor('#999999')
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position)
})
}
@Builder linearLayoutContent(item, position) {
Text(`${item}`)
.width('100%')
.height('100%')
.backgroundColor(0x22EEEEEE)
.border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid })
.fontSize(25)
.fontColor('#999999')
.fontWeight(FontWeight.Bold)
.maxLines(1)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.onClick(() => {
console.info('position = ' + position)
})
}
build() {
List() {
ListItem() {
STICKY_LAYOUT({
vLayoutContent: (item, position) => {
this.stickyLayoutContent(item, position)
},
vLayoutData: ['STICKY'],
vLayoutAttribute: {
aspectRatio: 4,
bgColor: '#22EEEEEE',
}
})
}.sticky(Sticky.Normal)
ListItem() {
LINEAR_LAYOUT({
vLayoutContent: (item, position) => {
this.linearLayoutContent(item, position)
},
vLayoutData: [0, 1, 2, 3, 4, 5, 6],
vLayoutAttribute: {
aspectRatio: 2,
padding: [5, 5, 5, 5],
},
})
}
}.edgeEffect(EdgeEffect.None)
}
在下述版本验证通过:
|---- vlayout
| |---- entry # 示例代码文件夹
| |---- vlayout # vlayout库文件夹
| |---- index.ets # 对外接口
| |---- src
| |---- main
| |---- ets
| |---- components
| |---- common # 组件文件夹
| |---- BannerLayoutHelper.ets # 滑动容器布局组件
| |---- ColumnLayoutHelper.ets # 横向容器布局组件
| |---- DefaultLayoutHelper.ets # 默认线性容器布局组件
| |---- FixLayoutHelper.ets # 固定容器布局组件
| |---- FloatLayoutHelper.ets # 浮动容器布局组件
| |---- GridLayoutHelper.ets # 宫格容器布局组件
| |---- JumpBar.ets # 跳转功能栏
| |---- LinearLayoutHelper.ets # 列表容器布局组件
| |---- OnePlusNLayoutHelper.ets # 一拖多容器布局组件
| |---- OnePlusNLayoutHelperEx.ets # 一拖多拓展容器布局组件
| |---- RangeGridLayoutHelper.ets # 区域宫格容器布局组件
| |---- ScrollFixLayoutHelper.ets # 滚动固定容器布局组件
| |---- SingleLayoutHelper.ets # 单项容器布局组件
| |---- StaggeredGridLayoutHelper.ets # 瀑布流容器布局组件
| |---- StickyLayoutHelper.ets # 吸顶吸底容器布局组件
| |---- core # 属性文件夹
| |---- VLayoutAttributes.ets # 容器布局组件的属性
| |---- README.md # 安装使用方法
使用过程中发现任何问题都可以提 Issue 给我们,当然,我们也非常欢迎你给我们发 PR 。
本项目基于 Apache License 2.0 ,请自由地享受和参与开源。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。