Grid
網格容器,由“行”和“列”分割的單元格所組成,通過指定“項目”所在的單元格做出各種各樣的布局。
說明:
開發前請熟悉鴻蒙開發指導文檔 :[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]
該組件從API Version 7開始支持。后續版本如有新增內容,則采用上角標單獨標記該內容的起始版本。
子組件
僅支持[GridItem]子組件。
說明:
Grid子組件的索引值計算規則:
按子組件的順序依次遞增。
if/else語句中,只有條件成立分支內的子組件會參與索引值計算,條件不成立分支內的子組件不計算索引值。
ForEach/LazyForEach語句中,會計算展開所有子節點索引值。
[if/else]、[ForEach]和[LazyForEach]發生變化以后,會更新子節點索引值。
Grid子組件的visibility屬性設置為Hidden或None時依然會計算索引值。
Grid子組件的visibility屬性設置為None時不顯示,但依然會占用子組件對應的網格。
Grid子組件設置position屬性,會占用子組件對應的網格,子組件將顯示在相對Grid左上角偏移position的位置。該子組件不會隨其對應網格滾動,在對應網格滑出Grid顯示范圍外后不顯示。
接口
Grid(scroller?: Scroller, layoutOptions?: GridLayoutOptions)
參數:
參數名 | 參數類型 | 必填 | 參數描述 |
---|---|---|---|
scroller | [Scroller] | 否 | 可滾動組件的控制器。用于與可滾動組件進行綁定。**說明:**不允許和其他[滾動類組件]綁定同一個滾動控制對象。 |
layoutOptions10+ | GridLayoutOptions | 否 | 滾動Grid布局選項。 |
GridLayoutOptions10+
布局選項,配合rowsTemplate、columnsTemplate僅設置其中一個的Grid使用,可以替代通過columnStart/columnEnd控制GridItem占用多列、rowStart/rowEnd控制GridItem占用多行的場景。
參數:
名稱 | 類型 | 必填 | 描述 |
---|---|---|---|
regularSize | [number, number] | 是 | 大小規則的GridItem在Grid中占的行數和列數,只支持占1行1列即[1, 1]。 |
irregularIndexes | number[] | 否 | 大小不規則的GridItem在Grid所有子節點中的索引值。onGetIrregularSizeByIndex不設置時irregularIndexes中的GridItem默認占垂直滾動Grid的一整行或水平滾動Grid的一整列。 |
onGetIrregularSizeByIndex | (index: number) => [number, number] | 否 | 獲取不規則GridItem占用的行數和列數,布局過程中針對irregularIndexes中的index調用,開發者應返回index對應GridItem占用的行數和列數。垂直滾動Grid不支持GridItem占多行,水平滾動Grid不支持GridItem占多列。 |
屬性
除支持[通用屬性]外,還支持以下屬性:
名稱 | 參數類型 | 描述 |
---|---|---|
columnsTemplate | string | 設置當前網格布局列的數量或最小列寬值,不設置時默認1列。 例如, '1fr 1fr 2fr' 是將父組件分3列,將父組件允許的寬分為4等份,第一列占1份,第二列占1份,第三列占2份。 ‘repeat(auto-fit, 90px)’是設置最小列寬值為90,自動計算列數和實際列寬。**說明:**設置為'0fr'時,該列的列寬為0,不顯示GridItem。設置為其他非法值時,GridItem顯示為固定1列。 |
rowsTemplate | string | 設置當前網格布局行的數量或最小行高值,不設置時默認1行。 例如, '1fr 1fr 2fr'是將父組件分三行,將父組件允許的高分為4等份,第一行占1份,第二行占一份,第三行占2份。 ‘repeat(auto-fit, 90px)’是設置最小行高值為90,自動計算行數和實際行高。**說明:**設置為'0fr',則這一行的行寬為0,這一行GridItem不顯示。設置為其他非法值,按固定1行處理。 |
columnsGap | [Length] | 設置列與列的間距。 默認值:0**說明:**設置為小于0的值時,按默認值顯示。 |
rowsGap | [Length] | 設置行與行的間距。 默認值:0**說明:**設置為小于0的值時,按默認值顯示。 |
scrollBar | [BarState] | 設置滾動條狀態。 默認值:BarState.Off**說明:**API version 9及以下版本默認值為BarState.Off,API version 10的默認值為BarState.Auto。 |
scrollBarColor | string | number |
scrollBarWidth | string | number |
cachedCount | number | 設置預加載的GridItem的數量,只在[LazyForEach]中生效。具體使用可參考[減少應用白塊說明]。 默認值:1**說明:**設置緩存后會在Grid顯示區域上下各緩存cachedCount*列數個GridItem。 [LazyForEach]超出顯示和緩存范圍的GridItem會被釋放。 設置為小于0的值時,按默認值顯示。 |
editMode 8+ | boolean | 設置Grid是否進入編輯模式,進入編輯模式可以拖拽Grid組件內部[GridItem]。 默認值:flase |
layoutDirection8+ | [GridDirection] | 設置布局的主軸方向。 默認值:GridDirection.Row |
maxCount8+ | number | 當layoutDirection是Row/RowReverse時,表示可顯示的最大列數 當layoutDirection是Column/ColumnReverse時,表示可顯示的最大行數。 默認值:Infinity**說明:**當maxCount小于minCount時,maxCount和minCount都按默認值處理。 設置為小于1的值時,按默認值顯示。 |
minCount8+ | number | 當layoutDirection是Row/RowReverse時,表示可顯示的最小列數。 當layoutDirection是Column/ColumnReverse時,表示可顯示的最小行數。 默認值:1**說明:**設置為小于1的值時,按默認值顯示。 |
cellLength8+ | number | 當layoutDirection是Row/RowReverse時,表示一行的高度。 當layoutDirection是Column/ColumnReverse時,表示一列的寬度。 默認值:第一個元素的大小 |
multiSelectable8+ | boolean | 是否開啟鼠標框選。 默認值:false - false:關閉框選。 - true:開啟框選。**說明:**開啟框選后,可以配合Griditem的selected屬性和onSelect事件獲取GridItem的選中狀態,還可以設置[選中態樣式](無默認選中樣式)。 |
supportAnimation8+ | boolean | 是否支持動畫。當前支持GridItem拖拽動畫。 默認值:false**說明:**僅在滾動模式下(只設置rowsTemplate、columnsTemplate其中一個)支持動畫。 |
edgeEffect10+ | [EdgeEffect] | 設置組件的滑動效果,支持彈簧效果和陰影效果。 默認值:EdgeEffect.None |
enableScrollInteraction10+ | boolean | 設置是否支持滾動手勢,當設置為false時,無法通過手指或者鼠標滾動,但不影響控制器的滾動接口。 默認值:true |
nestedScroll10+ | [NestedScrollOptions] | 嵌套滾動選項。設置向前向后兩個方向上的嵌套滾動模式,實現與父組件的滾動聯動。 |
friction10+ | number | [Resource] |
Grid組件根據rowsTemplate、columnsTemplate屬性的設置情況,可分為以下三種布局模式:
1、rowsTemplate、columnsTemplate同時設置:
- Grid只展示固定行列數的元素,其余元素不展示,且Grid不可滾動。
- 此模式下以下屬性不生效:layoutDirection、maxCount、minCount、cellLength。
- Grid的寬高沒有設置時,默認適應父組件尺寸。
- Gird網格列大小按照Gird自身內容區域大小減去所有行列Gap后按各個行列所占比重分配。
- GridItem默認填滿網格大小。
2、rowsTemplate、columnsTemplate僅設置其中的一個:
- 元素按照設置的方向進行排布,超出Grid顯示區域后,Grid可通過滾動的方式展示。
- 如果設置了columnsTemplate,Gird滾動方向為垂直方向,主軸方向為垂直方向,交叉軸方向為水平方向。
- 如果設置了rowsTemplate,Gird滾動方向為水平方向,主軸方向為水平方向,交叉軸方向為垂直方向。
- 此模式下以下屬性不生效:layoutDirection、maxCount、minCount、cellLength。
- 網格交叉軸方向尺寸根據Gird自身內容區域交叉軸尺寸減去交叉軸方向所有Gap后按所占比重分配。
- 網格主軸方向尺寸取當前網格交叉軸方向所有GridItem高度最大值。
3、rowsTemplate、columnsTemplate都不設置:
- 元素在layoutDirection方向上排布,列數由Grid的寬度、首個元素的寬度、minCount、maxCount、columnsGap共同決定。
- 行數由Grid高度、首個元素高度、cellLength、rowsGap共同決定。超出行列容納范圍的元素不顯示,也不能通過滾動進行展示。
- 此模式下僅生效以下屬性:layoutDirection、maxCount、minCount、cellLength、editMode、columnsGap、rowsGap。
- 當前layoutDirection設置為Row時,先從左到右排列,排滿一行再排一下一列。剩余高度不足時不再布局,整體內容頂部居中。
- 當前layoutDirection設置為Column時,先從上到下排列,排滿一列再排一下一列,剩余寬度度不足時不再。整體內容頂部居中。
GridDirection8+枚舉說明
名稱 | 描述 |
---|---|
Row | 主軸布局方向沿水平方向布局,即自左往右先填滿一行,再去填下一行。 |
Column | 主軸布局方向沿垂直方向布局,即自上往下先填滿一列,再去填下一列。 |
RowReverse | 主軸布局方向沿水平方向反向布局,即自右往左先填滿一行,再去填下一行。 |
ColumnReverse | 主軸布局方向沿垂直方向反向布局,即自下往上先填滿一列,再去填下一列。 |
說明:
Grid組件[通用屬性clip]的默認值為true。
事件
除支持[通用事件]外,還支持以下事件:
名稱 | 功能描述 |
---|---|
onScrollIndex(event: (first: number, last10+: number) => void) | 當前網格顯示的起始位置/終止位置的item發生變化時觸發。網格初始化時會觸發一次。 - first: 當前顯示的網格起始位置的索引值。 - last: 當前顯示的網格終止位置的索引值。 Grid顯示區域上第一個子組件/最后一個組件的索引值有變化就會觸發。 |
onItemDragStart(event: (event: ItemDragInfo, itemIndex: number) => (() => any) | void) |
onItemDragEnter(event: (event: ItemDragInfo) => void) | 拖拽進入網格元素范圍內時觸發。 - event: 見[ItemDragInfo對象說明]。 |
onItemDragMove(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number) => void) | 拖拽在網格元素范圍內移動時觸發。 - event: 見[ItemDragInfo對象說明]。 - itemIndex: 拖拽起始位置。 - insertIndex: 拖拽插入位置。 |
onItemDragLeave(event: (event: ItemDragInfo, itemIndex: number) => void) | 拖拽離開網格元素時觸發。 - event: 見[ItemDragInfo對象說明]。 - itemIndex: 拖拽離開的網格元素索引值。 |
onItemDrop(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => void) | 綁定該事件的網格元素可作為拖拽釋放目標,當在網格元素內停止拖拽時觸發。 - event: 見[ItemDragInfo對象說明]。 - itemIndex: 拖拽起始位置。 - insertIndex: 拖拽插入位置。 - isSuccess: 是否成功釋放。 |
onScrollBarUpdate(event: (index: number, offset: number) => ComputedBarAttribute) | 當前網格顯示的起始位置item發生變化時觸發,可通過該回調設置滾動條的位置及長度。 - index: 當前顯示的網格起始位置的索引值。 - offset: 當前顯示的網格起始位置元素相對網格顯示起始位置的偏移。 - ComputedBarAttribute: 見[ComputedBarAttribute對象說明]。 |
onScroll10+(event: (scrollOffset: number, scrollState: ScrollState) => void) | 網格滑動時觸發。 - scrollOffset: 每幀滾動的偏移量,Grid的內容向上滾動時偏移量為正,向下滾動時偏移量為負。 - [scrollState]: 當前滑動狀態。 |
onReachStart10+(event: () => void) | 網格到達起始位置時觸發。**說明:**Grid初始化時如果initialIndex為0會觸發一次,Grid滾動到起始位置時觸發一次。Grid邊緣效果為彈簧效果時,劃動經過起始位置時觸發一次,回彈回起始位置時再觸發一次。 |
onReachEnd10+(event: () => void) | 網格到底末尾位置時觸發。**說明:**Grid邊緣效果為彈簧效果時,劃動經過末尾位置時觸發一次,回彈回末尾位置時再觸發一次。 |
onScrollFrameBegin10+(event: (offset: number, state: ScrollState) => { offsetRemain }) | 網格開始滑動時觸發,事件參數傳入即將發生的滑動量,事件處理函數中可根據應用場景計算實際需要的滑動量并作為事件處理函數的返回值返回,網格將按照返回值的實際滑動量進行滑動。 - offset:即將發生的滑動量,單位vp。 - state:當前滑動狀態。 - offsetRemain:實際滑動量,單位vp。 觸發該事件的條件:手指拖動Grid、Grid慣性劃動時每幀開始時觸發;Grid超出邊緣回彈、使用滾動控制器的滾動不會觸發。**說明:**當gridDirection的值為Axis.Vertical時,返回垂直方向滑動量,當gridDirection的值為Axis.Horizontal時,返回水平方向滑動量。 |
onScrollStart10+(event: () => void) | 網格滑動開始時觸發。手指拖動網格或網格的滾動條觸發的滑動開始時,會觸發該事件。使用[Scroller]滑動控制器觸發的帶動畫的滑動,動畫開始時會觸發該事件。 |
onScrollStop10+(event: () => void) | 網格滑動停止時觸發。手指拖動網格或網格的滾動條觸發的滑動,手指離開屏幕并且滑動停止時會觸發該事件;使用[Scroller]滑動控制器觸發的帶動畫的滑動,動畫停止會觸發該事件。 |
ItemDragInfo對象說明
名稱 | 類型 | 描述 |
---|---|---|
x | number | 當前拖拽點的x坐標。 |
y | number | 當前拖拽點的y坐標。 |
ComputedBarAttribute對象說明
名稱 | 類型 | 描述 |
---|---|---|
totalOffset | number | Grid內容相對顯示區域的總偏移。 |
totalLength | number | Grid內容總長度。HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿 |
示例
示例1
// xxx.ets
@Entry
@Component
struct GridExample {
@State Number: String[] = ['0', '1', '2', '3', '4']
scroller: Scroller = new Scroller()
build() {
Column({ space: 5 }) {
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: string) = > day)
}, (day: string) = > day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%')
Grid(this.scroller) {
ForEach(this.Number, (day: string) = > {
ForEach(this.Number, (day: string) = > {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height(80)
.textAlign(TextAlign.Center)
}
}, (day: string) = > day)
}, (day: string) = > day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.friction(0.6)
.edgeEffect(EdgeEffect.Spring)
.scrollBar(BarState.On)
.onScrollIndex((first: number) = > {
console.info(first.toString())
})
.onScrollBarUpdate((index: number, offset: number) = > {
return {totalOffset: (index / 5) * (80 + 10) - offset, totalLength: 80 * 5 + 10 * 4}
})
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
Button('next page')
.onClick(() = > { // 點擊后滑到下一頁
this.scroller.scrollPage({ next: true })
})
}.width('100%').margin({ top: 5 })
}
}
示例2
- 設置屬性editMode(true)設置Grid是否進入編輯模式,進入編輯模式可以拖拽Grid組件內部GridItem。
- 在[onItemDragStart]回調中設置拖拽過程中顯示的圖片。
- 在[onItemDrop]中獲取拖拽起始位置,和拖拽插入位置,在[onDrag]回調中完成交換數組位置邏輯。
@Entry
@Component
struct GridExample {
@State numbers: string[] = []
scroller: Scroller = new Scroller()
@State text: string = 'drag'
@Builder pixelMapBuilder() { //拖拽過程樣式
Column() {
Text(this.text)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width(80)
.height(80)
.textAlign(TextAlign.Center)
}
}
aboutToAppear() {
for (let i = 1;i <= 15; i++) {
this.numbers.push(i + '')
}
}
changeIndex(index1: number, index2: number) { //交換數組位置
let temp: string;
temp = this.numbers[index1];
this.numbers[index1] = this.numbers[index2];
this.numbers[index2] = temp;
}
build() {
Column({ space: 5 }) {
Grid(this.scroller) {
ForEach(this.numbers, (day: string) = > {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width(80)
.height(80)
.textAlign(TextAlign.Center)
}
})
}
.columnsTemplate('1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.onScrollIndex((first: number) = > {
console.info(first.toString())
})
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
.editMode(true) //設置Grid是否進入編輯模式,進入編輯模式可以拖拽Grid組件內部GridItem
.onItemDragStart((event: ItemDragInfo, itemIndex: number) = > { //第一次拖拽此事件綁定的組件時,觸發回調。
this.text = this.numbers[itemIndex]
return this.pixelMapBuilder() //設置拖拽過程中顯示的圖片。
})
.onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) = > { //綁定此事件的組件可作為拖拽釋放目標,當在本組件范圍內停止拖拽行為時,觸發回調。
// isSuccess=false時,說明drop的位置在grid外部;insertIndex > length時,說明有新增元素的事件發生
if (!isSuccess || insertIndex >= this.numbers.length) {
return
}
console.info('beixiang' + itemIndex + '', insertIndex + '') //itemIndex拖拽起始位置,insertIndex拖拽插入位置
this.changeIndex(itemIndex, insertIndex)
})
}.width('100%').margin({ top: 5 })
}
}
示例圖:
網格子組件開始拖拽:
網格子組件拖拽過程中:
網格子組件1與子組件6拖拽交換位置后:
示例3
使用GridLayoutOptions
// xxx.ets
@Entry
@Component
struct GridExample {
@State Number: String[] = ['0', '1', '2', '3', '4']
scroller: Scroller = new Scroller()
layoutOptions1: GridLayoutOptions = {
regularSize: [1, 1], // 只支持[1, 1]
irregularIndexes: [0, 6], // 索引為0和6的GridItem占用一行
}
layoutOptions2: GridLayoutOptions = {
regularSize: [1, 1],
irregularIndexes: [0, 7], // 索引為0和7的GridItem占用的列數由onGetIrregularSizeByIndex指定
onGetIrregularSizeByIndex: (index: number) = > {
if (index === 0) {
return [1, 5]
}
return [1, index % 6 + 1]
}
}
build() {
Column({ space: 5 }) {
Grid(this.scroller, this.layoutOptions1) {
ForEach(this.Number, (day: string) = > {
ForEach(this.Number, (day: string) = > {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height(80)
.textAlign(TextAlign.Center)
}
}, (day: string) = > day)
}, (day: string) = > day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.scrollBar(BarState.Off)
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%')
// 不使用scroll,需要undefined占位
Grid(undefined, this.layoutOptions2) {
ForEach(this.Number, (day: string) = > {
ForEach(this.Number, (day: string) = > {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height(80)
.textAlign(TextAlign.Center)
}
}, (day: string) = > day)
}, (day: string) = > day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.scrollBar(BarState.Off)
.width('90%')
.backgroundColor(0xFAEEE0)
.height(300)
}.width('100%').margin({ top: 5 })
}
}
審核編輯 黃宇
-
Grid
+關注
關注
0文章
8瀏覽量
9596 -
鴻蒙
+關注
關注
57文章
2345瀏覽量
42822
發布評論請先 登錄
相關推薦
評論