柵格布局(GridRow/GridCol)

2024-01-25 13:11 更新

概述

柵格布局是一種通用的輔助定位工具,對(duì)移動(dòng)設(shè)備的界面設(shè)計(jì)有較好的借鑒作用。主要優(yōu)勢(shì)包括:

  1. 提供可循的規(guī)律:柵格布局可以為布局提供規(guī)律性的結(jié)構(gòu),解決多尺寸多設(shè)備的動(dòng)態(tài)布局問題。通過將頁(yè)面劃分為等寬的列數(shù)和行數(shù),可以方便地對(duì)頁(yè)面元素進(jìn)行定位和排版。
  2. 統(tǒng)一的定位標(biāo)注:柵格布局可以為系統(tǒng)提供一種統(tǒng)一的定位標(biāo)注,保證不同設(shè)備上各個(gè)模塊的布局一致性。這可以減少設(shè)計(jì)和開發(fā)的復(fù)雜度,提高工作效率。
  3. 靈活的間距調(diào)整方法:柵格布局可以提供一種靈活的間距調(diào)整方法,滿足特殊場(chǎng)景布局調(diào)整的需求。通過調(diào)整列與列之間和行與行之間的間距,可以控制整個(gè)頁(yè)面的排版效果。
  4. 自動(dòng)換行和自適應(yīng):柵格布局可以完成一對(duì)多布局的自動(dòng)換行和自適應(yīng)。當(dāng)頁(yè)面元素的數(shù)量超出了一行或一列的容量時(shí),他們會(huì)自動(dòng)換到下一行或下一列,并且在不同的設(shè)備上自適應(yīng)排版,使得頁(yè)面布局更加靈活和適應(yīng)性強(qiáng)。

GridRow為柵格容器組件,需與柵格子組件GridCol在柵格布局場(chǎng)景中聯(lián)合使用。

柵格容器GridRow

柵格系統(tǒng)斷點(diǎn)

柵格系統(tǒng)以設(shè)備的水平寬度(屏幕密度像素值,單位vp)作為斷點(diǎn)依據(jù),定義設(shè)備的寬度類型,形成了一套斷點(diǎn)規(guī)則。開發(fā)者可根據(jù)需求在不同的斷點(diǎn)區(qū)間實(shí)現(xiàn)不同的頁(yè)面布局效果。

柵格系統(tǒng)默認(rèn)斷點(diǎn)將設(shè)備寬度分為xs、sm、md、lg四類,尺寸范圍如下:

斷點(diǎn)名稱

取值范圍(vp)

設(shè)備描述

xs

[0, 320)

最小寬度類型設(shè)備。

sm

[320, 520)

小寬度類型設(shè)備。

md

[520, 840)

中等寬度類型設(shè)備。

lg

[840, +∞)

大寬度類型設(shè)備。

在GridRow柵格組件中,允許開發(fā)者使用breakpoints自定義修改斷點(diǎn)的取值范圍,最多支持6個(gè)斷點(diǎn),除了默認(rèn)的四個(gè)斷點(diǎn)外,還可以啟用xl,xxl兩個(gè)斷點(diǎn),支持六種不同尺寸(xs, sm, md, lg, xl, xxl)設(shè)備的布局設(shè)置。

斷點(diǎn)名稱

設(shè)備描述

xs

最小寬度類型設(shè)備。

sm

小寬度類型設(shè)備。

md

中等寬度類型設(shè)備。

lg

大寬度類型設(shè)備。

xl

特大寬度類型設(shè)備。

xxl

超大寬度類型設(shè)備。

  • 針對(duì)斷點(diǎn)位置,開發(fā)者根據(jù)實(shí)際使用場(chǎng)景,通過一個(gè)單調(diào)遞增數(shù)組設(shè)置。由于breakpoints最多支持六個(gè)斷點(diǎn),單調(diào)遞增數(shù)組長(zhǎng)度最大為5。

    1. breakpoints: {value: ['100vp', '200vp']}

    表示啟用xs、sm、md共3個(gè)斷點(diǎn),小于100vp為xs,100vp-200vp為sm,大于200vp為md。

    1. breakpoints: {value: ['320vp', '520vp', '840vp', '1080vp']}

    表示啟用xs、sm、md、lg、xl共5個(gè)斷點(diǎn),小于320vp為xs,320vp-520vp為sm,520vp-840vp為md,840vp-1080vp為lg,大于1080vp為xl。

  • 柵格系統(tǒng)通過監(jiān)聽窗口或容器的尺寸變化進(jìn)行斷點(diǎn),通過reference設(shè)置斷點(diǎn)切換參考物。 考慮到應(yīng)用可能以非全屏窗口的形式顯示,以應(yīng)用窗口寬度為參照物更為通用。

例如,使用柵格的默認(rèn)列數(shù)12列,通過斷點(diǎn)設(shè)置將應(yīng)用寬度分成六個(gè)區(qū)間,在各區(qū)間中,每個(gè)柵格子元素占用的列數(shù)均不同。

  1. @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
  2. ...
  3. GridRow({
  4. breakpoints: {
  5. value: ['200vp', '300vp', '400vp', '500vp', '600vp'],
  6. reference: BreakpointsReference.WindowSize
  7. }
  8. }) {
  9. ForEach(this.bgColors, (color, index) => {
  10. GridCol({
  11. span: {
  12. xs: 2, // 在最小寬度類型設(shè)備上,柵格子組件占據(jù)的柵格容器2列。
  13. sm: 3, // 在小寬度類型設(shè)備上,柵格子組件占據(jù)的柵格容器3列。
  14. md: 4, // 在中等寬度類型設(shè)備上,柵格子組件占據(jù)的柵格容器4列。
  15. lg: 6, // 在大寬度類型設(shè)備上,柵格子組件占據(jù)的柵格容器6列。
  16. xl: 8, // 在特大寬度類型設(shè)備上,柵格子組件占據(jù)的柵格容器8列。
  17. xxl: 12 // 在超大寬度類型設(shè)備上,柵格子組件占據(jù)的柵格容器12列。
  18. }
  19. }) {
  20. Row() {
  21. Text(`${index}`)
  22. }.width("100%").height('50vp')
  23. }.backgroundColor(color)
  24. })
  25. }

布局的總列數(shù)

GridRow中通過columns設(shè)置柵格布局的總列數(shù)。

  • columns默認(rèn)值為12,即在未設(shè)置columns時(shí),任何斷點(diǎn)下,柵格布局被分成12列。

    1. @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown,Color.Red, Color.Orange, Color.Yellow, Color.Green];
    2. ...
    3. GridRow() {
    4. ForEach(this.bgColors, (item, index) => {
    5. GridCol() {
    6. Row() {
    7. Text(`${index + 1}`)
    8. }.width('100%').height('50')
    9. }.backgroundColor(item)
    10. })
    11. }

  • 當(dāng)columns為自定義值,柵格布局在任何尺寸設(shè)備下都被分為columns列。下面分別設(shè)置柵格布局列數(shù)為4和8,子元素默認(rèn)占一列,效果如下:

    1. @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
    2. @State currentBp: string = 'unknown';
    3. ...
    4. Row() {
    5. GridRow({ columns: 4 }) {
    6. ForEach(this.bgColors, (item, index) => {
    7. GridCol() {
    8. Row() {
    9. Text(`${index + 1}`)
    10. }.width('100%').height('50')
    11. }.backgroundColor(item)
    12. })
    13. }
    14. .width('100%').height('100%')
    15. .onBreakpointChange((breakpoint) => {
    16. this.currentBp = breakpoint
    17. })
    18. }
    19. .height(160)
    20. .border({ color: Color.Blue, width: 2 })
    21. .width('90%')
    22. Row() {
    23. GridRow({ columns: 8 }) {
    24. ForEach(this.bgColors, (item, index) => {
    25. GridCol() {
    26. Row() {
    27. Text(`${index + 1}`)
    28. }.width('100%').height('50')
    29. }.backgroundColor(item)
    30. })
    31. }
    32. .width('100%').height('100%')
    33. .onBreakpointChange((breakpoint) => {
    34. this.currentBp = breakpoint
    35. })
    36. }
    37. .height(160)
    38. .border({ color: Color.Blue, width: 2 })
    39. .width('90%')

  • 當(dāng)columns類型為GridRowColumnOption時(shí),支持下面六種不同尺寸(xs, sm, md, lg, xl, xxl)設(shè)備的總列數(shù)設(shè)置,各個(gè)尺寸下數(shù)值可不同。

    1. @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown]
    2. GridRow({ columns: { sm: 4, md: 8 }, breakpoints: { value: ['200vp', '300vp', '400vp', '500vp', '600vp'] } }) {
    3. ForEach(this.bgColors, (item, index) => {
    4. GridCol() {
    5. Row() {
    6. Text(`${index + 1}`)
    7. }.width('100%').height('50')
    8. }.backgroundColor(item)
    9. })
    10. }

    若只設(shè)置sm, md的柵格總列數(shù),則較小的尺寸使用默認(rèn)columns值12,較大的尺寸使用前一個(gè)尺寸的columns。這里只設(shè)置sm:4, md:8,則較小尺寸的xs:12,較大尺寸的參照md的設(shè)置,lg:8, xl:8, xxl:8。

排列方向

柵格布局中,可以通過設(shè)置GridRow的direction屬性來指定柵格子組件在柵格容器中的排列方向。該屬性可以設(shè)置為GridRowDirection.Row(從左往右排列)或GridRowDirection.RowReverse(從右往左排列),以滿足不同的布局需求。通過合理的direction屬性設(shè)置,可以使得頁(yè)面布局更加靈活和符合設(shè)計(jì)要求。

  • 子組件默認(rèn)從左往右排列。

    1. GridRow({ direction: GridRowDirection.Row }){}

  • 子組件從右往左排列。

    1. GridRow({ direction: GridRowDirection.RowReverse }){}

子組件間距

GridRow中通過gutter屬性設(shè)置子元素在水平和垂直方向的間距。

  • 當(dāng)gutter類型為number時(shí),同時(shí)設(shè)置柵格子組件間水平和垂直方向邊距且相等。下例中,設(shè)置子組件水平與垂直方向距離相鄰元素的間距為10。

    1. GridRow({ gutter: 10 }){}

  • 當(dāng)gutter類型為GutterOption時(shí),單獨(dú)設(shè)置柵格子組件水平垂直邊距,x屬性為水平方向間距,y為垂直方向間距。

    1. GridRow({ gutter: { x: 20, y: 50 } }){}

子組件GridCol

GridCol組件作為GridRow組件的子組件,通過給GridCol傳參或者設(shè)置屬性兩種方式,設(shè)置span(占用列數(shù)),offset(偏移列數(shù)),order(元素序號(hào))的值。

  • 設(shè)置span。

    1. GridCol({ span: 2 }){}
    2. GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 } }){}
    3. GridCol(){}.span(2)
    4. GridCol(){}.span({ xs: 1, sm: 2, md: 3, lg: 4 })
  • 設(shè)置offset。

    1. GridCol({ offset: 2 }){}
    2. GridCol({ offset: { xs: 2, sm: 2, md: 2, lg: 2 } }){}
    3. GridCol(){}.offset(2)
    4. GridCol(){}.offset({ xs: 1, sm: 2, md: 3, lg: 4 })
  • 設(shè)置order。

    1. GridCol({ order: 2 }){}
    2. GridCol({ order: { xs: 1, sm: 2, md: 3, lg: 4 } }){}
    3. GridCol(){}.order(2)
    4. GridCol(){}.order({ xs: 1, sm: 2, md: 3, lg: 4 })

span

子組件占柵格布局的列數(shù),決定了子組件的寬度,默認(rèn)為1。

  • 當(dāng)類型為number時(shí),子組件在所有尺寸設(shè)備下占用的列數(shù)相同。

    1. @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
    2. ...
    3. GridRow({ columns: 8 }) {
    4. ForEach(this.bgColors, (color, index) => {
    5. GridCol({ span: 2 }) {
    6. Row() {
    7. Text(`${index}`)
    8. }.width('100%').height('50vp')
    9. }
    10. .backgroundColor(color)
    11. })
    12. }

  • 當(dāng)類型為GridColColumnOption時(shí),支持六種不同尺寸(xs, sm, md, lg, xl, xxl)設(shè)備中子組件所占列數(shù)設(shè)置,各個(gè)尺寸下數(shù)值可不同。

    1. @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
    2. ...
    3. GridRow({ columns: 8 }) {
    4. ForEach(this.bgColors, (color, index) => {
    5. GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 } }) {
    6. Row() {
    7. Text(`${index}`)
    8. }.width('100%').height('50vp')
    9. }
    10. .backgroundColor(color)
    11. })
    12. }

offset

柵格子組件相對(duì)于前一個(gè)子組件的偏移列數(shù),默認(rèn)為0。

  • 當(dāng)類型為number時(shí),子組件偏移相同列數(shù)。

    1. @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
    2. ...
    3. GridRow() {
    4. ForEach(this.bgColors, (color, index) => {
    5. GridCol({ offset: 2 }) {
    6. Row() {
    7. Text('' + index)
    8. }.width('100%').height('50vp')
    9. }
    10. .backgroundColor(color)
    11. })
    12. }

    柵格默認(rèn)分成12列,每一個(gè)子組件默認(rèn)占1列,偏移2列,每個(gè)子組件及間距共占3列,一行放四個(gè)子組件。

  • 當(dāng)類型為GridColColumnOption時(shí),支持六種不同尺寸(xs, sm, md, lg, xl, xxl)設(shè)備中子組件所占列數(shù)設(shè)置,各個(gè)尺寸下數(shù)值可不同。

    1. @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
    2. ...
    3. GridRow() {
    4. ForEach(this.bgColors, (color, index) => {
    5. GridCol({ offset: { xs: 1, sm: 2, md: 3, lg: 4 } }) {
    6. Row() {
    7. Text('' + index)
    8. }.width('100%').height('50vp')
    9. }
    10. .backgroundColor(color)
    11. })
    12. }

order

柵格子組件的序號(hào),決定子組件排列次序。當(dāng)子組件不設(shè)置order或者設(shè)置相同的order, 子組件按照代碼順序展示。當(dāng)子組件設(shè)置不同的order時(shí),order較小的組件在前,較大的在后。

當(dāng)子組件部分設(shè)置order,部分不設(shè)置order時(shí),未設(shè)置order的子組件依次排序靠前,設(shè)置了order的子組件按照數(shù)值從小到大排列。

  • 當(dāng)類型為number時(shí),子組件在任何尺寸下排序次序一致。

    1. GridRow() {
    2. GridCol({ order: 4 }) {
    3. Row() {
    4. Text('1')
    5. }.width('100%').height('50vp')
    6. }.backgroundColor(Color.Red)
    7. GridCol({ order: 3 }) {
    8. Row() {
    9. Text('2')
    10. }.width('100%').height('50vp')
    11. }.backgroundColor(Color.Orange)
    12. GridCol({ order: 2 }) {
    13. Row() {
    14. Text('3')
    15. }.width('100%').height('50vp')
    16. }.backgroundColor(Color.Yellow)
    17. GridCol({ order: 1 }) {
    18. Row() {
    19. Text('4')
    20. }.width('100%').height('50vp')
    21. }.backgroundColor(Color.Green)
    22. }

  • 當(dāng)類型為GridColColumnOption時(shí),支持六種不同尺寸(xs, sm, md, lg, xl, xxl)設(shè)備中子組件排序次序設(shè)置。在xs設(shè)備中,子組件排列順序?yàn)?234;sm為2341,md為3412,lg為2431。

    1. GridRow() {
    2. GridCol({ order: { xs:1, sm:5, md:3, lg:7}}) {
    3. Row() {
    4. Text('1')
    5. }.width('100%').height('50vp')
    6. }.backgroundColor(Color.Red)
    7. GridCol({ order: { xs:2, sm:2, md:6, lg:1} }) {
    8. Row() {
    9. Text('2')
    10. }.width('100%').height('50vp')
    11. }.backgroundColor(Color.Orange)
    12. GridCol({ order: { xs:3, sm:3, md:1, lg:6} }) {
    13. Row() {
    14. Text('3')
    15. }.width('100%').height('50vp')
    16. }.backgroundColor(Color.Yellow)
    17. GridCol({ order: { xs:4, sm:4, md:2, lg:5} }) {
    18. Row() {
    19. Text('4')
    20. }.width('100%').height('50vp')
    21. }.backgroundColor(Color.Green)
    22. }

柵格組件的嵌套使用

柵格組件也可以嵌套使用,完成一些復(fù)雜的布局。

以下示例中,柵格把整個(gè)空間分為12份。第一層GridRow嵌套GridCol,分為中間大區(qū)域以及“footer”區(qū)域。第二層GridRow嵌套GridCol,分為“l(fā)eft”和“right”區(qū)域。子組件空間按照上一層父組件的空間劃分,粉色的區(qū)域是屏幕空間的12列,綠色和藍(lán)色的區(qū)域是父組件GridCol的12列,依次進(jìn)行空間的劃分。

  1. @Entry
  2. @Component
  3. struct GridRowExample {
  4. build() {
  5. GridRow() {
  6. GridCol({ span: { sm: 12 } }) {
  7. GridRow() {
  8. GridCol({ span: { sm: 2 } }) {
  9. Row() {
  10. Text('left').fontSize(24)
  11. }
  12. .justifyContent(FlexAlign.Center)
  13. .height('90%')
  14. }.backgroundColor('#ff41dbaa')
  15. GridCol({ span: { sm: 10 } }) {
  16. Row() {
  17. Text('right').fontSize(24)
  18. }
  19. .justifyContent(FlexAlign.Center)
  20. .height('90%')
  21. }.backgroundColor('#ff4168db')
  22. }
  23. .backgroundColor('#19000000')
  24. .height('100%')
  25. }
  26. GridCol({ span: { sm: 12 } }) {
  27. Row() {
  28. Text('footer').width('100%').textAlign(TextAlign.Center)
  29. }.width('100%').height('10%').backgroundColor(Color.Pink)
  30. }
  31. }.width('100%').height(300)
  32. }
  33. }

綜上所述,柵格組件提供了豐富的自定義能力,功能異常靈活和強(qiáng)大。只需要明確柵格在不同斷點(diǎn)下的Columns、Margin、Gutter及span等參數(shù),即可確定最終布局,無(wú)需關(guān)心具體的設(shè)備類型及設(shè)備狀態(tài)(如橫豎屏)等。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)