HarmonyOS開發(fā)之GridRow&GridCol

GridRow/GridCol(柵格布局)

GridRow/GridCol(柵格布局)是響應(yīng)式布局的一種,響應(yīng)式布局可以實(shí)現(xiàn)界面隨外部容器尺寸分級不連續(xù)變化而變化。

所以GridRow/GridCol(柵格布局)的適用場景:隨尺寸變化組件結(jié)構(gòu)不同的場景,比如:外部容器大小發(fā)生變化時,組件元素可以根據(jù)斷點(diǎn)、柵格或特定的特征(如橫豎屏方向切換、窗口寬高變化,不同設(shè)備的尺寸等)自動變化以適應(yīng)外部容器變化的布局能力

GridRow:柵格容器組件,需與結(jié)合其子組件GridCol開發(fā),可以適配不同尺寸的設(shè)備,讓各個設(shè)備可以合理的顯示,以此亦完成不同屏幕尺寸的UI適配。

一、GridRow參數(shù):breakpoints、columns和gutter(文章里會詳細(xì)說明)

斷點(diǎn):breakpoint

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

為了便于理解,通過下面的示例代碼進(jìn)行說明。閱覽示例代碼可知,brerakpoints是GridRow的參數(shù)。value(數(shù)組)和reference(枚舉值)是breakpoints的兩個成員變量。

示例代碼:breakpoints: {?

value: ['300vp','600vp','800vp','1000vp','1200vp'],

?reference:BreakpointsReference.WindowSize

?}

1、WindowSize:reference的默認(rèn)值為BreakpointsReference.WindowSize,此值表示是以設(shè)備的寬度作為參照,通過屏寬與value內(nèi)的每個元素進(jìn)行比較。跟設(shè)備有關(guān),因為不同設(shè)備,屏寬可能不同。

屏寬屬于[0, 300vp)就是xs,表示最小寬度類型設(shè)備。(屏寬 < 300)

屏寬屬于[300, 600vp)就是sm,表示小寬度類型設(shè)備。(屏寬 >= 300 && 屏寬 < 600)

屏寬屬于[600, 800vp)就是md,表示中等寬度類型設(shè)備。

屏寬屬于[800, 1000vp)就lg,表示大寬度類型設(shè)備。

屏寬屬于[1000, 1200vp)就是xl,表示特大寬度類型設(shè)備。

屏寬屬于[1200, +∞)就是xxl,表示超大寬度類型設(shè)備。

2、ComponentSize:若reference的值為BreakpointsReference.ComponentSize,表示是以容器(GridRow)的尺寸作為參照,通過容器的width與value內(nèi)的每個元素進(jìn)行比較,比較原理與屏寬一致。

需要注意:因為此時是用容器的尺寸的進(jìn)行比較,所以與當(dāng)前的設(shè)備就無關(guān)了(若按設(shè)備百分比設(shè)置寬度,那跟屏寬還是有關(guān)系的)。

重點(diǎn)說明:在示例代碼中,values =??['300vp', '600vp', '800vp', '1000vp', '1200vp'],但values中元素的值是不固定的,理論上只要從小到大排列即可,但這需要跟當(dāng)前的需求做出相應(yīng)的調(diào)整,因為官方要求最多只能有xs、sm、md、lg、xl、xxl六個斷點(diǎn),所以value中最多只能有五個元素,若只有四個元素,則xxl自動失效,可省去,以此類推,若里面只有一個元素,那就意味著所有情況都只有xs[0, '300vp')和sm['300vp', +∞)兩個斷點(diǎn)。

span中的xs等斷點(diǎn)所傳入的值是所占列數(shù),不理解可以暫時先跳過,下面會詳細(xì)講解

@Entry

@Component

struct Index {

? @State gridRowWidth: number = 200;

? colors: Color[] = [Color.Red, Color.Yellow, Color.Pink, Color.Orange, Color.Brown, Color.Blue, Color.Orange, Color.Gray]

? build() {

? ? Column() {

? ? ? GridRow({

? ? ? ? breakpoints: {

? ? ? ? ? value: ['300vp', '600vp', '800vp', '1000vp', '1200vp'],

? ? ? ? ? // reference: BreakpointsReference.WindowSize, // 以設(shè)備尺寸作為參照,跟設(shè)備有關(guān)

? ? ? ? ? reference: BreakpointsReference.ComponentSize // 以容器組件尺寸作為參照,絕對尺寸,此處與設(shè)備無關(guān)

? ? ? ? },

? ? ? ? direction: GridRowDirection.Row // 排列方式:從左至右

? ? ? }) {

? ? ? ? ForEach(this.colors, (item: Color, index: Number) => {

? ? ? ? ? GridCol({

? ? ? ? ? ? span: {

? ? ? ? ? ? ? xs: 12, //設(shè)備/容器組件寬度在【0, 300) 之間,即為xs。 在最小寬度類型設(shè)備上,GridCol占據(jù)的GridRow中的12列。

? ? ? ? ? ? ? sm: 6, // 設(shè)備/容器組件寬度在【300, 600) 之間,即為sm。在小寬度類型設(shè)備上,GridCol占據(jù)的GridRow中的6列。

? ? ? ? ? ? ? md: 4, // 設(shè)備/容器組件寬度在【600, 800) 之間,即為md。在中等寬度類型設(shè)備上,GridCol占據(jù)的GridRow中的4列。

? ? ? ? ? ? ? lg: 3, // 設(shè)備/容器組件寬度在【800, 1000) 之間,即為lg。在大寬度類型設(shè)備上,GridCol占據(jù)的GridRow中的3列。

? ? ? ? ? ? ? xl: 2, // 設(shè)備/容器組件寬度在【1000, 1300) 之間,即為xl。在特大寬度類型設(shè)備上,GridCol占據(jù)的GridRow中的2列。

? ? ? ? ? ? ? xxl: 1 // 設(shè)備/容器組件寬度在【1200, +∞)之間,即為xxl。在超大寬度類型設(shè)備上,GridCol占據(jù)的GridRow中的1列。

? ? ? ? ? ? }

? ? ? ? ? }) {

? ? ? ? ? ? Row() {

? ? ? ? ? ? ? Text(index.toString())

? ? ? ? ? ? ? ? .fontSize(20)

? ? ? ? ? ? ? ? .fontWeight(FontWeight.Bold)

? ? ? ? ? ? ? ? .width('100%')

? ? ? ? ? ? ? ? .textAlign(TextAlign.Center)

? ? ? ? ? ? ? ? .onClick(() => {

? ? ? ? ? ? ? ? ? this.gridRowWidth += 50; //修改容器組件GridRow的寬度,用于測試,前提:以容器組件為參照

? ? ? ? ? ? ? ? })

? ? ? ? ? ? }.width('100%').height(50)

? ? ? ? ? }

? ? ? ? ? .backgroundColor(item)

? ? ? ? }, (item: Color) => item.toString())

? ? ? }

? ? ? .width(`${this.gridRowWidth}vp`)

? ? ? .height(500)

? ? ? .backgroundColor('#f5f5f5')

? ? }

? ? .width('100%')

? }

}


columns

columns默認(rèn)值是12,即在不設(shè)此參數(shù)時,默認(rèn)12列,也可以自定義

同樣通過下面示例代碼進(jìn)行說明:

1、columns是一個復(fù)合值類型(number |?GridRowColumnOption)。

當(dāng)columns為number類型時,比如columns: 10,在任何情況下GridRow都被分為10列。下面分別設(shè)置GridRow列數(shù)為6和10,子元素分別占2列和5列,下面代碼就是columns為number類型的示例代碼。

當(dāng)columns類型為GridRowColumnOption時,比如columns: { sm: 4, md: 8 },表示在斷點(diǎn)為sm時,GridRow被分為4列;點(diǎn)斷為md時,GridRow被分為8列,其他情況默認(rèn)還是12列。GridRowColumnOption的代碼就不做演示了,原理大同小異。

gutter

gutter也是一個復(fù)合值類型(Length | GutterOption)。

當(dāng)gutter為Length類型時,例如:gutter: 20,表示GridCol之間的距離上下左右的距離均為20。

也可以為GutterOption類型,例如:gutter: {x:20, y: 10},表示水平方向間距20,垂直方向間距10。

備注:當(dāng)一行展示不下時,自動折行。

代碼與效果圖如下:

@Entry

@Component

struct Index {

? colors: Color[] = [

? ? Color.Red, Color.Yellow, Color.Pink, Color.Orange,

? ? Color.Brown, Color.Blue, Color.Yellow, Color.Orange,

? ? Color.Gray, Color.Pink, Color.Orange, Color.Brown];

? build() {

? ? Column({space: 30}) {

? ? ? GridRow({

? ? ? ? gutter: 20, // GridCol之間的間距為20,也可以設(shè)置為{x:20, y: 10},表示水平方向間距20,垂直方向間距10

? ? ? ? columns: 6 // 表示一共把GridRow的寬度分為6列(為了更好理解,可以理解成分為了6份)

? ? ? }) {

? ? ? ? ForEach(this.colors, (item: Color, index: Number) => {

? ? ? ? ? GridCol({

? ? ? ? ? ? span: 2 // 共6份,此設(shè)置表示占2份的寬度, 所以會展示3列

? ? ? ? ? }) {

? ? ? ? ? ? Row() {

? ? ? ? ? ? ? Text(index.toString())

? ? ? ? ? ? ? ? .fontSize(20)

? ? ? ? ? ? ? ? .fontWeight(FontWeight.Bold)

? ? ? ? ? ? ? ? .width('100%')

? ? ? ? ? ? ? ? .textAlign(TextAlign.Center)

? ? ? ? ? ? }.width('100%').height(50)

? ? ? ? ? }

? ? ? ? ? .backgroundColor(item)

? ? ? ? }, (item: Color) => item.toString())

? ? ? }

? ? ? .width('100%')

? ? ? .height(500)

? ? ? .backgroundColor('#f5f5f5')

? ? ? GridRow({

? ? ? ? gutter: {x: 20, y: 10}, // 表示為{x:20, y: 10},表示水平方向間距20,垂直方向間距10

? ? ? ? columns: 10 // 10列

? ? ? }){

? ? ? ? ForEach(this.colors, (item: Color, index: number) => {

? ? ? ? ? GridCol({

? ? ? ? ? ? span: 5 // 共10份,此設(shè)置表示占5份的寬度, 所以會展示2列

? ? ? ? ? }) {

? ? ? ? ? ? Row(){

? ? ? ? ? ? ? Text(index.toString())

? ? ? ? ? ? ? ? .fontSize(20)

? ? ? ? ? ? ? ? .fontWeight(FontWeight.Bold)

? ? ? ? ? ? ? ? .width('100%')

? ? ? ? ? ? ? ? .textAlign(TextAlign.Center)

? ? ? ? ? ? }

? ? ? ? ? ? .backgroundColor(item)

? ? ? ? ? ? .width('100%')

? ? ? ? ? ? .height(50)

? ? ? ? ? }

? ? ? ? }, (item: Color) => item.toString())

? ? ? }

? ? ? .width('100%')

? ? ? .height(500)

? ? ? .backgroundColor('#f5f5f5')

? ? }

? ? .width('100%')

? }

}


3、columns默認(rèn)值為12,沒傳入columns時,柵格布局被分成12列,與斷點(diǎn)無關(guān)了,如下代碼與效果圖如下:

@Entry

@Component

struct Index {

? colors: Color[] = [

? ? Color.Red, Color.Yellow, Color.Pink, Color.Orange,

? ? Color.Brown, Color.Blue, Color.Yellow, Color.Orange,

? ? Color.Gray, Color.Pink, Color.Orange, Color.Brown];

? build() {

? ? Column() {

? ? ? GridRow() {

? ? ? ? ForEach(this.colors, (item: Color, index: Number) => {

? ? ? ? ? GridCol() {

? ? ? ? ? ? Row() {

? ? ? ? ? ? ? Text(index.toString())

? ? ? ? ? ? ? ? .fontSize(20)

? ? ? ? ? ? ? ? .fontWeight(FontWeight.Bold)

? ? ? ? ? ? ? ? .width('100%')

? ? ? ? ? ? ? ? .textAlign(TextAlign.Center)

? ? ? ? ? ? }.width('100%').height(50)

? ? ? ? ? }

? ? ? ? ? .backgroundColor(item)

? ? ? ? }, (item: Color) => item.toString())

? ? ? }

? ? ? .width('100%')

? ? ? .height(500)

? ? ? .backgroundColor('#f5f5f5')

? ? }

? ? .width('100%')

? }

}

三、子組件GridCol的參數(shù):span、offset、order

1、span

也是一個復(fù)合值類型 (number | GridColColumnOption)。

當(dāng)span為number類型時,比如span: 4,表示所有情況GridCol都占4列。

當(dāng)span為GridColColumnOption類型時,如第一份代碼中,span{xs: 12}, 表示在對應(yīng)為xs斷點(diǎn)時,當(dāng)前的GridCol占12列。

2、offset

也是一個復(fù)合值類型 (number | GridColColumnOption),表示GridCol相對于前一個GridCol的偏移列數(shù),默認(rèn)為0。

當(dāng)類型為number時,GridCol偏移相同列數(shù)。例如:offset: 2,偏移量為2列

當(dāng)類型為GridColColumnOption時,例如:offset: { xs: 1, sm: 2, md: 3, lg: 4 },邏輯與span類型,分?jǐn)帱c(diǎn)情況設(shè)置的偏移量

當(dāng)一行的最后偏移量不夠時,需要換行繼續(xù)偏移

3、order

也是一個復(fù)合值類型 (number |?GridColColumnOption),表示GridCol當(dāng)前的排序編號,定GridCol排列次序。當(dāng)GridCol不設(shè)置order或者設(shè)置相同的order, GridCol按照代碼順序展示。GridCol排序是按order從小到大的排列。未設(shè)置order的GridCol依次排序靠前,設(shè)置了order的GridCol按照數(shù)值從小到大排列。

當(dāng)類型為number時。例如:order: 2,表示序號為2

當(dāng)類型為GridColColumnOption時,例如:offset: { xs: 1, sm: 2, md: 3, lg: 4 },邏輯與span類型,分?jǐn)帱c(diǎn)情況設(shè)置的序號

示例代碼和效果圖如下:

@Entry

@Component

struct Index {

? colors: Color[] = [

? ? Color.Red, Color.Yellow, Color.Pink, Color.Orange,

? ? Color.Brown, Color.Blue, Color.Yellow, Color.Orange,

? ? Color.Gray, Color.Pink, Color.Orange, Color.Brown];

? build() {

? ? Column({ space: 30 }) {

? ? ? GridRow({

? ? ? ? columns: 10 // 表示一共把GridRow的寬度分為10列

? ? ? }) {

? ? ? ? ForEach(this.colors, (item: Color, index: Number) => {

? ? ? ? ? GridCol({

? ? ? ? ? ? span: 2 // 共10份,此設(shè)置表示占2份的寬度, 所以會展示5列

? ? ? ? ? }) {

? ? ? ? ? ? Row() {

? ? ? ? ? ? ? Text(index.toString())

? ? ? ? ? ? ? ? .fontSize(20)

? ? ? ? ? ? ? ? .fontWeight(FontWeight.Bold)

? ? ? ? ? ? ? ? .width('100%')

? ? ? ? ? ? ? ? .textAlign(TextAlign.Center)

? ? ? ? ? ? }.width('100%').height(50)

? ? ? ? ? }

? ? ? ? ? .backgroundColor(item)

? ? ? ? }, (item: Color) => item.toString())

? ? ? }

? ? ? .width('100%')

? ? ? .height(500)

? ? ? .backgroundColor('#f5f5f5')

? ? ? GridRow({

? ? ? ? columns: 10 // 10列

? ? ? }) {

? ? ? ? ForEach(this.colors, (item: Color, index: number) => {

? ? ? ? ? GridCol({

? ? ? ? ? ? span: 2,

? ? ? ? ? ? offset: 2 // 子組件偏移相同列數(shù)2,當(dāng)一行的最后偏移量不夠時,需要換行繼續(xù)偏移。注意:此處偏移不是指行首子組件偏移,而是所有子組件都會偏移

? ? ? ? ? ? // offset: {xs: 2, sm: 3} // 與span屬性類似,也支持分?jǐn)帱c(diǎn)傳值

? ? ? ? ? }) {

? ? ? ? ? ? Row() {

? ? ? ? ? ? ? Text(index.toString())

? ? ? ? ? ? ? ? .fontSize(20)

? ? ? ? ? ? ? ? .fontWeight(FontWeight.Bold)

? ? ? ? ? ? ? ? .width('100%')

? ? ? ? ? ? ? ? .textAlign(TextAlign.Center)

? ? ? ? ? ? }

? ? ? ? ? ? .backgroundColor(item)

? ? ? ? ? ? .width('100%')

? ? ? ? ? ? .height(50)

? ? ? ? ? }

? ? ? ? }, (item: Color) => item.toString())

? ? ? }

? ? ? .width('100%')

? ? ? .height(500)

? ? ? .backgroundColor('#f5f5f5')

? ? ? GridRow({ columns: 12 }) {

? ? ? ? ForEach(this.colors, (item: Color, index: number) => {

? ? ? ? ? GridCol({

? ? ? ? ? ? span: 2,

? ? ? ? ? ? order: 12 - index // 與文案相反排列

????????????// order: { xs: 1, sm: 2, md: 3, lg: 4 } //與span屬性類似,也支持分?jǐn)帱c(diǎn)傳值

? ? ? ? ? }) {

? ? ? ? ? ? Row() {

? ? ? ? ? ? ? Text(index.toString())

? ? ? ? ? ? ? ? .fontSize(20)

? ? ? ? ? ? ? ? .fontWeight(FontWeight.Bold)

? ? ? ? ? ? ? ? .width('100%')

? ? ? ? ? ? ? ? .textAlign(TextAlign.Center)

? ? ? ? ? ? }

? ? ? ? ? ? .backgroundColor(item)

? ? ? ? ? ? .width('100%')

? ? ? ? ? ? .height(50)

? ? ? ? ? }

? ? ? ? }, (item: Color) => item.toString())

? ? ? }

}

? ? .width('100%')

? }

}


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容