# vlayout **Repository Path**: zhangjun93/vlayout ## Basic Information - **Project Name**: vlayout - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 21 - **Created**: 2022-05-20 - **Last Updated**: 2022-07-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vlayout ## 简介 > vlayout能够处理列表、网格和其他布局在同一个视图的复杂情况,且用户可以使用已设定好的容器布局组件,也可以在原有的基础上自定义容器布局组件。 ## 效果展示: 1. BANNER_LAYOUT滑动容器布局组件 2. COLUMN_LAYOUT横向容器布局组件 3. DEFAULT_LAYOUT默认容器布局组件 4. FIX_LAYOUT固定容器布局组件 5. FLOAT_LAYOUT浮动容器布局组件 6. GRID_LAYOUT复杂网格容器布局组件 7. LINEAR_LAYOUT列表容器布局组件 8. ONEN_LAYOUT一加多容器布局组件 9. ONEN_EX_LAYOUT一加多拓展容器布局组件 10. RANGEGRID_LAYOUT区域网格容器布局组件 11. SCROLL_FIX_LAYOUT滚动固定容器布局组件 12. SINGLE_LAYOUT单项容器布局组件 13. STAGGEREDGRID_LAYOUT交错网格容器布局组件 14. STICKY_LAYOUT吸顶容器布局组件 15. 跳转item项位置 ## 下载安装 1. 参考安装教程 [如何安装OpenHarmony npm包](https://gitee.com/openharmony-tpc/docs/blob/master/OpenHarmony_npm_usage.md) 2. 安装命令如下: ``` npm install @ohos/vlayout --save ``` ## 使用说明 ### 使用前言 1.通过eTS实现的vlayout与源库存在部分使用差异,在此会根据不同的容器组件来详细介绍基于openHarmony eTS实现的vlayout自定义容器组件的使用说明; 2.使用vlayout自定义容器组件需要给定最基本的三大要素:要显示的vLayoutContent布局内容、vLayoutData数据源以及vLayoutAttribute容器属性; 3.vlayout提供14种自定义容器组件,使用步骤主要分为两步:①导入需要使用的对应容器组件;②创建对应的容器组件对象并提供需要显示的布局内容; 4.局限性: ①vlayout建议在previewer屏宽720,屏高1280,DPI为160下进行预览; ②eTS原生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;具体使用demo请参考开源库sample页面的实现; ### 属性接口 1.在构建自定义容器组件时,必须给定以下属性 | 属性 | 是否必填 | 说明(不同布局组件存在不同的属性) | | ---------------------------- | -------- | ---------------------------------- | | vLayoutContent | 是 | 布局,使用@Builder构建自定义页面 | | vLayoutData: any[] | 是 | 数据源 | | vLayoutAttribute: Attributes | 是 | 属性类型 | 2.vlayout通过声明的方式进行属性的设置,为了方便管理各个容器布局类的属性,以下为vLayoutAttribute属性类,均为非必填属性 ``` export declare type GridAttributes = { /* * GridLayoutHelper * RangeGridLayoutHelper */ zIndex?: number //z序 topPadding?: Length //上内边距 rightPadding?: Length //右内边距 bottomPadding?: Length //下内边距 leftPadding?: Length //左内边距 topMargin?: Length //上外边距 rightMargin?: Length //右外边距 bottomMargin?: Length //下外边距 leftMargin?: Length //左外边距 aspectRatio?: number //单行纵横比 layoutHeight?: Length //容器高度 bgColor?: ResourceColor //容器背景颜色 spanCount?: number //列数,默认值为1 weight?: Array //列占比集合:列数即数组长度,元素数值约分为占比,元素之和为布局所占宽度,默认值为[100] autoExpand?: boolean //宽度自适应,当weight未定义时有效,且与colsSpan存在互斥关系,默认值为true vGap?: Length //列与列的间距 hGap?: Length //行与行的间距 } export declare type StaggeredGridAttributes = { /* * StaggeredGridLayoutHelper */ zIndex?: number //z序 topPadding?: Length //上内边距 rightPadding?: Length //右内边距 bottomPadding?: Length //下内边距 leftPadding?: Length //左内边距 topMargin?: Length //上外边距 rightMargin?: Length //右外边距 bottomMargin?: Length //下外边距 leftMargin?: Length //左外边距 bgColor?: ResourceColor //容器背景颜色 lanes?: number //一行展示的列数,默认值为1 gap?: number //每个item的上下左右间距,默认值为0 staggeredBorderWidth?: Length //每个item的边框宽度 staggeredBorderColor?: ResourceColor //每个item的边框颜色 staggeredBorderRadius?: Length //每个item的边框圆角半径 staggeredBorderStyle?: BorderStyle //每个item的边框样式 } export declare type AbstractFullFillAttributes = { /* * ColumnLayoutHelper * SingleLayoutHelper * OnePlusNLayoutHelper * OnePlusNLayoutHelperEx */ zIndex?: number //z序 topPadding?: Length //上内边距 rightPadding?: Length //右内边距 bottomPadding?: Length //下内边距 leftPadding?: Length //左内边距 topMargin?: Length //上外边距 rightMargin?: Length //右外边距 bottomMargin?: Length //下外边距 leftMargin?: Length //左外边距 layoutWidth?: Length //容器宽度,默认值为'100%' layoutHeight?: Length //容器高度,当容器纵横比为0时有效,默认值为120 aspectRatio?: number //容器纵横比,默认值为4 bgColor?: ResourceColor //容器背景颜色 hasHeader?: boolean //第一个子项变成一行一列,只有OnePlusNLayoutHelper支持 hasFooter?: boolean //最后一个子项变成一行一列,只有OnePlusNLayoutHelper支持 } export declare type BannerAttributes = { /* * BannerLayoutHelper */ zIndex?: number //z序 topPadding?: Length //上内边距 rightPadding?: Length //右内边距 bottomPadding?: Length //下内边距 leftPadding?: Length //左内边距 topMargin?: Length //上外边距 rightMargin?: Length //右外边距 bottomMargin?: Length //下外边距 leftMargin?: Length //左外边距 layoutWidth?: Length //容器宽度,默认值为'100%' layoutHeight?: Length //容器高度,默认值为100 aspectRatio?: number //容器纵横比,默认值为5 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 } export declare type LinearAttributes = { /* * LinearLayoutHelper * DefaultLayoutHelper */ zIndex?: number //z序 topPadding?: Length //上内边距 rightPadding?: Length //右内边距 bottomPadding?: Length //下内边距 leftPadding?: Length //左内边距 topMargin?: Length //上外边距 rightMargin?: Length //右外边距 bottomMargin?: Length //下外边距 leftMargin?: Length //左外边距 layoutWidth?: Length //容器宽度 layoutHeight?: Length //容器高度 aspectRatio?: number //容器纵横比 bgColor?: ResourceColor //容器颜色 layoutListSpace?: number | string //列表项垂直间距 isDifferentHeight?: boolean //是否为不同高度 } export declare type FixAreaAttributes = { /* * FloatLayoutHelper * FixLayoutHelper * ScrollFixLayoutHelper * StickyLayoutHelper */ zIndex?: number //z序 topPadding?: Length //上内边距 rightPadding?: Length //右内边距 bottomPadding?: Length //下内边距 leftPadding?: Length //左内边距 topMargin?: Length //上外边距 rightMargin?: Length //右外边距 bottomMargin?: Length //下外边距 leftMargin?: Length //左外边距 layoutWidth?: Length //容器宽度 layoutHeight?: Length //容器高度,当容器纵横比为0时有效 aspectRatio?: number //容器纵横比 bgColor?: ResourceColor //容器背景颜色 xOffset?: Length //水平偏移量,默认值为'1.4%',只有StickyLayoutHelper不支持 yOffset?: Length //竖直偏移量,只有StickyLayoutHelper不支持 sketchMeasure?: boolean //宽度占满屏幕,只有FixLayoutHelper, ScrollFixLayoutHelper支持 stickyStart?: boolean //true:吸顶,false:吸底,只有StickyLayoutHelper支持 } ``` ### GRID_LAYOUT复杂网格宫格容器使用 1.导入GRID_LAYOUT容器 ``` import {GRID_LAYOUT} from '@ohos/vlayout' ``` 2.创建GRID_LAYOUT对象并提供需要显示的布局内容 ``` @Builder gridLayoutContent(vLayoutData) { Text(`${vLayoutData.layoutText}`) .width('100%') .height('100%') .backgroundColor(0x22EEEEEE) .border({ width: 1, color: '#000000', radius: 0, style: BorderStyle.Solid }) .fontColor(0x999999) .fontSize(25) .fontWeight(FontWeight.Bold) .textAlign(TextAlign.Center) } build() { Column() { GRID_LAYOUT({ vLayoutContent: (vLayoutData) => { this.gridLayoutContent(vLayoutData) }, vLayoutData: [ { layoutText: 1 }, { layoutText: 2 }, { layoutText: 3 }, { layoutText: 4 }, { layoutText: 5 }, { layoutText: 6 }, { layoutText: 7 }, { layoutText: 8, colsSpan: 2 } ], vLayoutAttribute: { layoutHeight: 480, oneRowHeight: 240, aspectRatio: 3, bgColor: '#AAAAAA', spanCount: 3, weight: [50], }, vLayoutId: 'grid' }) } } ``` ### RANGEGRID_LAYOUT区域网格宫格容器使用 1.导入RANGEGRID_LAYOUT容器 ``` import { RANGEGRID_LAYOUT } from '@ohos/vlayout' ``` 2.创建RANGEGRID_LAYOUT对象并提供需要显示的布局内容 ``` @Builder rangeGridLayoutContent(item, position, height) { 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 }) } .backgroundColor(item.layoutColor) .padding({ top: Number(`${item.columnStart}`) && Number(`${item.columnEnd}`) != null ? 5 : 0, right: Number(`${item.columnStart}`) && Number(`${item.columnEnd}`) != null ? 5.5 : 0, bottom: Number(`${item.columnStart}`) && Number(`${item.columnEnd}`) != null ? 5 : 0, left: Number(`${item.columnStart}`) && Number(`${item.columnEnd}`) != null ? 5.5 : 0, }) .margin({ top: Number(`${item.columnStart}`) && Number(`${item.columnEnd}`) != null ? position == 6 || position == 7 || position == 10 || position == 11 ? 0 : 0 : 0, right: Number(`${item.columnStart}`) && Number(`${item.columnEnd}`) != null ? position % 2 == 0 ? 0 : 15 : 0, bottom: Number(`${item.columnStart}`) && Number(`${item.columnEnd}`) != null ? position == 4 || position == 5 || position == 8 || position == 9 ? 0 : 10 : 0, left: Number(`${item.columnStart}`) && Number(`${item.columnEnd}`) != null ? position % 2 != 0 ? 0 : 15 : 0, }) } build() { Column() { RANGEGRID_LAYOUT({ vLayoutContent: (itemData, position, height) => { this.rangeGridLayoutContent(itemData, position, height) }, vLayoutData: [ { layoutText: 15, layoutColor: '#00FF00' }, { layoutText: 16, layoutColor: '#00FF00' }, { layoutText: 17, layoutColor: '#00FF00' }, { layoutText: 18, layoutColor: '#00FF00' }, { layoutText: 19, columnStart: 1, columnEnd: 2, layoutColor: '#FF0000' }, { layoutText: 20, columnStart: 1, columnEnd: 2, layoutColor: '#FF0000' }, { layoutText: 21, columnStart: 1, columnEnd: 2, layoutColor: '#FF0000' }, { layoutText: 22, columnStart: 1, columnEnd: 2, layoutColor: '#FF0000' }, { layoutText: 23, columnStart: 1, columnEnd: 2, layoutColor: '#FFFF00' }, { layoutText: 24, columnStart: 1, columnEnd: 2, layoutColor: '#FFFF00' }, { layoutText: 25, columnStart: 1, columnEnd: 2, layoutColor: '#FFFF00' }, { layoutText: 26, columnStart: 1, columnEnd: 2, layoutColor: '#FFFF00' }, { layoutText: 27, layoutColor: '#00FF00' }, { layoutText: 28, layoutColor: '#00FF00' }, { layoutText: 29, layoutColor: '#00FF00' }, { layoutText: 30, layoutColor: '#00FF00' }, ], vLayoutAttribute: { aspectRatio: 3, bgColor: '#00FF00', spanCount: 4, weight: [20, 26.6, 26.6, 26.6], topPadding: 10, rightPadding: 10, bottomPadding: 10, leftPadding: 10, topMargin: 10, rightMargin: 10, bottomMargin: 10, leftMargin: 10, }, vLayoutId: 'rangeGrid' }) } } ``` ### STAGGEREDGRID_LAYOUT瀑布流交错网格宫格容器使用 1.导入STAGGEREDGRID_LAYOUT容器 ``` import { STAGGEREDGRID_LAYOUT } from '@ohos/vlayout' ``` 2.创建STAGGEREDGRID_LAYOUT对象并提供需要显示的布局内容 ``` @State data: any[] = [ { layoutData: [ { layoutText: 155, layoutHeight: 330 }, { layoutText: 156, layoutHeight: 220 }, { layoutText: 157, layoutHeight: 330 }, { layoutText: 158, layoutHeight: 280 }, { layoutText: 159, layoutHeight: 330 }, { layoutText: 160, layoutHeight: 220 }, { layoutText: 161, layoutHeight: 330 }, { layoutText: 162, layoutHeight: 220 }, { layoutText: 163, layoutHeight: 330 }, { layoutText: 164, layoutHeight: 330 }, { layoutText: 165, layoutHeight: 330 }, { layoutText: 166, layoutHeight: 220 }, { layoutText: 167, layoutHeight: 330 }, { layoutText: 168, layoutHeight: 330 }, { layoutText: 169, layoutHeight: 330 }, { layoutText: 170, layoutHeight: 220 }, { layoutText: 171, layoutHeight: 330 }, { layoutText: 172, layoutHeight: 330 }, { layoutText: 173, layoutHeight: 330 }, { layoutText: 174, layoutHeight: 220 }, { layoutText: 175, layoutHeight: 330 }, { layoutText: 176, layoutHeight: 220 }, { layoutText: 177, layoutHeight: 330 }, { layoutText: 178, layoutHeight: 220 }, { layoutText: 179, layoutHeight: 330 }, { layoutText: 180, layoutHeight: 220 }, { layoutText: 181, layoutHeight: 330 }, ] }, //STAGGEREDGRID_LAYOUT ] @Builder staggeredGridLayoutContent(vLayoutData, position) { Text(`${vLayoutData.layoutText}`) .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('position = ' + position) }) } build() { Scroll() { STAGGEREDGRID_LAYOUT({ vLayoutContent: (vLayoutData, position) => { this.staggeredGridLayoutContent(vLayoutData, position) }, vLayoutData: this.data[0].layoutData, vLayoutAttribute: { bgColor: 0xFF86345A, lanes: 3, gap: 10, topMargin: 5, rightMargin: 3, bottomMargin: 5, leftMargin: 2, } }) } } ``` ### COLUMN_LAYOUT横向容器使用 1.导入COLUMN_LAYOUT容器 ``` import { COLUMN_LAYOUT } from '@ohos/vlayout' ``` 2.创建COLUMN_LAYOUT对象并提供需要显示的布局内容 ``` @Builder columnLayoutContent(layoutContent) { Row() { ForEach(layoutContent, (item: any) => { 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 }) .layoutWeight(item.layoutWeight) .onClick(() => { console.log(item.layoutText); }) }) } } build() { Column() { COLUMN_LAYOUT({ vLayoutContent: (layoutContent) => { this.columnLayoutContent(layoutContent) }, vLayoutData: [ { layoutText: 32, layoutWeight: 15 }, { layoutText: 33, layoutWeight: 1 }, { layoutText: 34, layoutWeight: 15 }, { layoutText: 35, layoutWeight: 1 }, { layoutText: 36, layoutWeight: 1 }, ], vLayoutAttribute: { layoutWidth: '100%', layoutHeight: 100, aspectRatio: 15, bgColor: '#ff00f0f0', bottomMargin: 5, } }) } } ``` ### SINGLE_LAYOUT单项容器使用 1.导入SINGLE_LAYOUT容器 ``` import { SINGLE_LAYOUT } from '@ohos/vlayout' ``` 2.创建SINGLE_LAYOUT对象并提供需要显示的布局内容 ``` @Builder singleLayoutContent() { Column() { Text('9') .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 }) } } build() { Column() { SINGLE_LAYOUT({ vLayoutContent: () => { this.singleLayoutContent() }, vLayoutAttribute: { layoutWidth: '100%', layoutHeight: 70, aspectRatio: 0, bgColor: Color.Blue, topMargin: 5, bottomMargin: 90, } }) } } ``` ### ONEN_LAYOUT一拖多容器使用 1.导入ONEN_LAYOUT容器 ``` import { ONEN_LAYOUT }from '@ohos/vlayout' ``` 2.创建ONEN_LAYOUT对象并提供需要显示的布局内容 ``` @Builder onenLayoutContent(vLayoutData) { Text(`${vLayoutData.layoutText}`) .width(`${vLayoutData.layoutWidth}`) .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 }) } build() { Column() { ONEN_LAYOUT({ vLayoutContent: (vLayoutData) => { this.onenLayoutContent(vLayoutData) }, vLayoutData: [ { layoutText: 18, layoutWidth: '100%', outerRowsWeight: 1, }, { layoutText: 19, layoutWidth: '100%', outerRowsWeight: 1, innerColsWeight: 1, }, { layoutText: 20, layoutWidth: '100%', innerColsWeight: 1, innerRowsWeight: 1, }, { layoutText: 21, layoutWidth: '100%', innerRowsWeight: 1, }, { layoutText: 22, layoutWidth: '100%', innerRowsWeight: 1, }, ], vLayoutAttribute: { layoutWidth: '100%', layoutHeight: 120, aspectRatio: 4, bgColor: '#ff876384', topPadding: 5, rightPadding: 5, bottomPadding: 5, leftPadding: 5, topMargin: 5, bottomMargin: 5, } }) } } ``` ### ONEN_EX_LAYOUT一拖多拓展容器使用 1.导入ONEN_EX_LAYOUT容器 ``` import { ONEN_EX_LAYOUT }from '@ohos/vlayout' ``` 2.创建ONEN_EX_LAYOUT对象并提供需要显示的布局内容 ``` @Builder onenExLayoutContent(vLayoutData) { Text(`${vLayoutData.layoutText}`) .width(`${vLayoutData.layoutWidth}`) .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 }) } build() { Column() { ONEN_EX_LAYOUT({ vLayoutContent: (vLayoutData) => { this.onenExLayoutContent(vLayoutData) }, vLayoutData: [ { layoutText: 23, layoutWidth: '100%', outerRowsWeight: 1 }, { layoutText: 24, layoutWidth: '100%', outerRowsWeight: 2, outerColsWeight: 1, innerRowsWeight: 1, }, { layoutText: 25, layoutWidth: '100%', innerRowsWeight: 1, }, { layoutText: 26, layoutWidth: '100%', outerColsWeight: 1, innerRowsWeight: 1, }, { layoutText: 27, layoutWidth: '100%', innerRowsWeight: 1, }, ], vLayoutAttribute: { layoutWidth: '100%', layoutHeight: 100, aspectRatio: 4, bgColor: '#ff876384', topPadding: 5, rightPadding: 5, bottomPadding: 5, leftPadding: 5, topMargin: 5, bottomMargin: 5, } }) } } ``` ### BANNER_LAYOUT滑动容器使用 1.导入BANNER_LAYOUT容器 ``` import { BANNER_LAYOUT }from '@ohos/vlayout' ``` 2.创建BANNER_LAYOUT对象并提供需要显示的布局内容 ``` @Builder bannerLayoutContent(item: string) { Column() { 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 }) } } build() { Column() { BANNER_LAYOUT({ vLayoutContent: (item) => { this.bannerLayoutContent(`${item}`) }, vLayoutData: [0, 1, 2, 3, 4, 5], vLayoutAttribute: { layoutWidth: '100%', layoutHeight: 100, aspectRatio: 5, bgColor: '#AAAAAA', }, }) } } ``` ### LINEAR_LAYOUT列表容器使用 1.导入LINEAR_LAYOUT容器 ``` import { LINEAR_LAYOUT }from '@ohos/vlayout' ``` 2.创建LINEAR_LAYOUT对象并提供需要显示的布局内容 ``` @Builder linearLayoutContent(item: string, position: number) { Column() { 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 }) } } build() { Column() { LINEAR_LAYOUT({ vLayoutContent: (item, position) => { this.linearLayoutContent(`${item}`, position) }, vLayoutData: [3, 4, 5, 6, 7, 8], vLayoutAttribute: { layoutWidth: '100%', layoutHeight: 300, aspectRatio: 2, bgColor: Color.Yellow, topPadding: 5, rightPadding: 5, bottomPadding: 5, leftPadding: 5, topMargin: 5, rightMargin: 5, bottomMargin: 2, leftMargin: 5, }, }) } } ``` ### DEFAULT_LAYOUT默认线性容器使用 1.导入DEFAULT_LAYOUT容器 ``` import { DEFAULT_LAYOUT }from '@ohos/vlayout' ``` 2.创建DEFAULT_LAYOUT对象并提供需要显示的布局内容 ``` @Builder defaultLayoutContent(item: string, position: number) { Column() { 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.Top) .textOverflow({ overflow: TextOverflow.Ellipsis }) } } build() { Column() { DEFAULT_LAYOUT({ vLayoutContent: (item, position) => { this.defaultLayoutContent(`${item}`, position) }, vLayoutData: [8, 9], vLayoutAttribute: { layoutWidth: '100%', layoutHeight: 200, aspectRatio: 4, topMargin: 3, rightMargin: 5, bottomMargin: 5, leftMargin: 5, layoutListSpace: 5, } }) } } ``` ### FLOAT_LAYOUT浮动容器使用 1.导入FLOAT_LAYOUT容器 ``` import { FLOAT_LAYOUT } from '@ohos/vlayout' ``` 2.创建FLOAT_LAYOUT对象并提供需要显示的布局内容,由于浮动组件需要在父容器进行叠层显示,所以只推荐使用Stack为根布局 ``` private flayerShow: boolean = false //模拟块是否显示 private flayerWidth: number = 0 //模拟块宽度 private flayerHeight: number = 0 //模拟块高度 private flayerText: string = '' //模拟块文字内容 private flayerTextSize: number = 25 //模拟块文字大小 private flayerTextColor: Color = 0x999999 //模拟块文字颜色 private flayerBgColor: Color = 0xCFCFCF //模拟块背景颜色 @State xOffset: number | string = '75%' //位移坐标x @State yOffset: number | string = '75%' //位移坐标y @Builder floatLayoutContent(vLayoutData) { Stack() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { ForEach(vLayoutData, (item: any, index: number) => { Text(`${item.layoutText}`) .width(120) .height(120) .backgroundColor(0x22EEEEEE) .textAlign(TextAlign.Center) .fontColor(item.textColor) .fontSize(item.textSize) .borderWidth(1) .opacity(1) .onTouch((e: TouchEvent) => { if (e.type === TouchType.Down) { //拷贝块样式 let areaInfo = e.target.area //断言数据类型 this.flayerWidth = areaInfo.width as number this.flayerHeight = areaInfo.height as number this.flayerText = item.layoutText this.flayerTextSize = item.textSize this.flayerTextColor = item.textColor this.flayerBgColor = item.bgColor // @ts-ignore this.xOffset = areaInfo.globalPos.x as number // @ts-ignore this.yOffset = areaInfo.globalPos.y as number //拷贝完成,展示模拟块 this.flayerShow = true } else if (e.type === TouchType.Move) { this.xOffset = e.touches[0].screenX - this.flayerWidth / 2 this.yOffset = e.touches[0].screenY - this.flayerHeight / 2 } else if (e.type === TouchType.Up) { this.flayerShow = false var displayClass = null display.getDefaultDisplay().then((data) => { displayClass = data; //if (this.xOffset < (displayClass.width / 2)) { //在真机或板子上使用此行 if (this.xOffset < (720 / 2)) { //在预览器上使用此行,720为预览器屏宽 this.xOffset = 0 } else { //this.xOffset = displayClass.width - 120 //在真机或板子上使用此行 this.xOffset = 720 - 120 //在预览器上使用此行,720为预览器屏宽 } }).catch((err) => { console.log('something error: ' + JSON.stringify(err)); }); } }) }, (item: any, index: number) => item.toString()) } if (this.flayerShow) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Text(this.flayerText) .textAlign(TextAlign.Center) .fontColor(this.flayerTextColor) .fontSize(this.flayerTextSize) } .width(this.flayerWidth) .height(this.flayerHeight) .backgroundColor(this.flayerBgColor) .borderWidth(1) .opacity(1) } } } build() { Stack() { List() {...} FLOAT_LAYOUT({ vLayoutContent: (vLayoutData) => { this.floatLayoutContent(vLayoutData) }, vLayoutData: [ { layoutText: '1', textSize: 25, textColor: "#999999", bgColor: "#CFCFCF", }, ], xOffset: $xOffset, yOffset: $yOffset, vLayoutAttribute: { layoutWidth: 120, layoutHeight: 120, zIndex: 5, } }) } } ``` ### FIX_LAYOUT固定容器使用 1.导入FIX_LAYOUT容器 ``` import { FIX_LAYOUT } from '@ohos/vlayout' ``` 2.创建FIX_LAYOUT对象并提供需要显示的布局内容,由于固定组件需要在父容器进行叠层显示,所以只推荐使用Stack为根布局 ``` @Builder fixLayoutContent() { Column() { Text('50') .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 }) } } build() { Stack() { List() {...} FIX_LAYOUT({ vLayoutContent: () => { this.fixLayoutContent() }, vLayoutAttribute: { layoutWidth: 40, layoutHeight: 140, bgColor: 0x22EEEEEE, xOffset: '93%', yOffset: '1%', zIndex: 10, }, }) } } ``` ### SCROLL_FIX_LAYOUT滑动固定容器使用 1.导入SCROLL_FIX_LAYOUT容器 ``` import { SCROLL_FIX_LAYOUT } from '@ohos/vlayout' ``` 2.创建SCROLL_FIX_LAYOUT对象并提供需要显示的布局内容,由于滑动固定组件需要在父容器进行叠层显示并且需要在父容器滑动至某一位置之后出现,所以只推荐使用Stack为根布局,并且在父容器中进行实现该效果 ``` @Builder scrollFixLayoutContent() { Column() { Text('66') .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 }) } } build() { Stack() { List() {...} if (this.textFirst >= 65) { //65为某一容器的第一个子item项 SCROLL_FIX_LAYOUT({ vLayoutContent: () => { this.scrollFixLayoutContent() }, vLayoutAttribute: { layoutWidth: 30, layoutHeight: 30, bgColor: '#99AAAAAA', xOffset: '90%', yOffset: '95%', zIndex: 1, } }) } } } ``` ### STICKY_LAYOUT吸顶吸底容器使用 1.导入STICKY_LAYOUT容器 ``` import { STICKY_LAYOUT } from '@ohos/vlayout' ``` 2.创建STICKY_LAYOUT对象并提供需要显示的布局内容,由于吸顶组件需要在父容器进行叠层显示并且需要在父容器滑动至某一位置之后吸顶或吸底,所以只推荐使用Stack加List-ListItem为根布局,并且在父容器中进行实现该效果 ``` @Builder stickyLayoutContent() { Column() { Text('10') .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 }) } } @State stickyStart: boolean = true //吸顶或吸底 build() { Stack() { List() { ListItem() { STICKY_LAYOUT({ vLayoutContent: () => { this.stickyLayoutContent() }, vLayoutAttribute: { layoutWidth: '100%', layoutHeight: 170, aspectRatio: 4, bgColor: '#22EEEEEE', zIndex: 1, stickyStart: this.stickyStart, } }) }.sticky(this.stickyStart ? Sticky.Normal : Sticky.None) //吸顶 } if (this.textFirst < 3 && !this.stickyStart) { //吸底 STICKY_LAYOUT({ vLayoutContent: () => { this.stickyLayoutContent() }, vLayoutAttribute: { layoutWidth: '100%', layoutHeight: 170, aspectRatio: 0, bgColor: '#22EEEEEE', zIndex: 1, } }) } } } ``` ## 兼容性 支持 OpenHarmony API version 8 及以上版本。 ## 目录结构 ``` |---- 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](https://gitee.com/openharmony-sig/vlayout/issues)给我们,当然,我们也非常欢迎你给我们发 [PR](https://gitee.com/openharmony-sig/vlayout/pulls) 。 ## 开源协议 本项目基于 [Apache License 2.0](https://gitee.com/openharmony-sig/vlayout/blob/master/LICENSE) ,请自由地享受和参与开源。