W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
網(wǎng)格布局是由“行”和“列”分割的單元格所組成,通過指定“項(xiàng)目”所在的單元格做出各種各樣的布局。網(wǎng)格布局具有較強(qiáng)的頁面均分能力,子組件占比控制能力,是一種重要自適應(yīng)布局,其使用場景有九宮格圖片展示、日歷、計(jì)算器等。
ArkUI提供了Grid容器組件和子組件GridItem,用于構(gòu)建網(wǎng)格布局。Grid用于設(shè)置網(wǎng)格布局相關(guān)參數(shù),GridItem定義子組件相關(guān)特征。Grid組件支持使用條件渲染、循環(huán)渲染、懶加載等渲染控制方式生成子組件。
Grid組件為網(wǎng)格容器,其中容器內(nèi)每一個條目對應(yīng)一個GridItem組件,如下圖所示。
Grid的子組件必須是GridItem組件。
網(wǎng)格布局是一種二維布局。Grid組件支持自定義行列數(shù)和每行每列尺寸占比、設(shè)置子組件橫跨幾行或者幾列,同時提供了垂直和水平布局能力。當(dāng)網(wǎng)格容器組件尺寸發(fā)生變化時,所有子組件以及間距會等比例調(diào)整,從而實(shí)現(xiàn)網(wǎng)格布局的自適應(yīng)能力。根據(jù)Grid的這些布局能力,可以構(gòu)建出不同樣式的網(wǎng)格布局,如下圖所示。
如果Grid組件設(shè)置了寬高屬性,則其尺寸為設(shè)置值。如果沒有設(shè)置寬高屬性,Grid組件的尺寸默認(rèn)適應(yīng)其父組件的尺寸。
Grid組件根據(jù)行列數(shù)量與占比屬性的設(shè)置,可以分為三種布局情況:
通過設(shè)置行列數(shù)量與尺寸占比可以確定網(wǎng)格布局的整體排列方式。Grid組件提供了rowsTemplate和columnsTemplate屬性用于設(shè)置網(wǎng)格布局行列數(shù)量與尺寸占比。
rowsTemplate和columnsTemplate屬性值是一個由多個空格和'數(shù)字+fr'間隔拼接的字符串,fr的個數(shù)即網(wǎng)格布局的行或列數(shù),fr前面的數(shù)值大小,用于計(jì)算該行或列在網(wǎng)格布局寬度上的占比,最終決定該行或列的寬度。
如上圖所示,構(gòu)建的是一個三行三列的的網(wǎng)格布局,其在垂直方向上分為三等份,每行占一份;在水平方向上分為四等份,第一列占一份,第二列占兩份,第三列占一份。
只要將rowsTemplate的值為'1fr 1fr 1fr',同時將columnsTemplate的值為'1fr 2fr 1fr',即可實(shí)現(xiàn)上述網(wǎng)格布局。
- Grid() {
- ...
- }
- .rowsTemplate('1fr 1fr 1fr')
- .columnsTemplate('1fr 2fr 1fr')
當(dāng)Grid組件設(shè)置了rowsTemplate或columnsTemplate時,Grid的layoutDirection、maxCount、minCount、cellLength屬性不生效,屬性說明可參考Grid-屬性。
除了大小相同的等比例網(wǎng)格布局,由不同大小的網(wǎng)格組成不均勻分布的網(wǎng)格布局場景在實(shí)際應(yīng)用中十分常見,如下圖所示。在Grid組件中,通過設(shè)置GridItem的rowStart、rowEnd、columnStart和columnEnd可以實(shí)現(xiàn)如圖所示的單個網(wǎng)格橫跨多行或多列的場景。
例如計(jì)算器的按鍵布局就是常見的不均勻網(wǎng)格布局場景。如下圖,計(jì)算器中的按鍵“0”和“=”,按鍵“0”橫跨第一、二兩列,按鍵“=”橫跨第五、六兩行。使用Grid構(gòu)建的網(wǎng)格布局,其行列標(biāo)號從1開始,依次編號。
在單個網(wǎng)格單元中,rowStart和rowEnd屬性表示指定當(dāng)前元素起始行號和終點(diǎn)行號,columnStart和columnEnd屬性表示指定當(dāng)前元素的起始列號和終點(diǎn)列號。
所以“0”按鍵橫跨第一列和第二列,只要將“0”對應(yīng)GridItem的columnStart和columnEnd設(shè)為1和2,將“=”對應(yīng)GridItem的的rowStart和rowEnd設(shè)為5和6即可。
- GridItem() {
- Text(key)
- ...
- }
- .columnStart(1)
- .columnEnd(2)
“=”按鍵橫跨第五行和第六行,只要將將“=”對應(yīng)GridItem的的rowStart和rowEnd設(shè)為5和6即可。
- GridItem() {
- Text(key)
- ...
- }
- .rowStart(5)
- .rowEnd(6)
使用Grid構(gòu)建網(wǎng)格布局時,若沒有設(shè)置行列數(shù)量與占比,可以通過layoutDirection可以設(shè)置網(wǎng)格布局的主軸方向,決定子組件的排列方式。此時可以結(jié)合minCount和maxCount屬性來約束主軸方向上的網(wǎng)格數(shù)量。
當(dāng)前l(fā)ayoutDirection設(shè)置為Row時,先從左到右排列,排滿一行再排一下一行。當(dāng)前l(fā)ayoutDirection設(shè)置為Column時,先從上到下排列,排滿一列再排一下一列,如上圖所示。此時,將maxCount屬性設(shè)為3,表示主軸方向上最大顯示的網(wǎng)格單元數(shù)量為3。
- Grid() {
- ...
- }
- .maxCount(3)
- .layoutDirection(GridDirection.Row)
1. layoutDirection屬性僅在不設(shè)置rowsTemplate和columnsTemplate時生效,此時元素在layoutDirection方向上排列。
2. 僅設(shè)置rowsTemplate時,Grid主軸為水平方向,交叉軸為垂直方向。
2. 僅設(shè)置columnsTemplate時,Grid主軸為垂直方向,交叉軸為水平方向。
網(wǎng)格布局采用二維布局的方式組織其內(nèi)部元素,如下圖所示。
Grid組件可以通過二維布局的方式顯示一組GridItem子組件。
- Grid() {
- GridItem() {
- Text('會議')
- ...
- }
- GridItem() {
- Text('簽到')
- ...
- }
- GridItem() {
- Text('投票')
- ...
- }
- GridItem() {
- Text('打印')
- ...
- }
- }
- .rowsTemplate('1fr 1fr')
- .columnsTemplate('1fr 1fr')
對于內(nèi)容結(jié)構(gòu)相似的多個GridItem,通常更推薦使用循環(huán)渲染ForEach語句中嵌套GridItem的形式,來減少重復(fù)代碼。
- @Component
- struct OfficeService {
- @State services: Array<string> = ['會議', '投票', '簽到', '打印']
- ...
- build() {
- Column() {
- Grid() {
- ForEach(this.services, service => {
- GridItem() {
- Text(service)
- ...
- }
- }, service => service)
- }
- .rowsTemplate('1fr 1fr')
- .columnsTemplate('1fr 1fr')
- ...
- }
- ...
- }
- }
在兩個網(wǎng)格單元之間的網(wǎng)格橫向間距稱為行間距,網(wǎng)格縱向間距稱為列間距,如下圖所示。
通過Grid的rowsGap和columnsGap可以設(shè)置網(wǎng)格布局的行列間距。在圖5所示的計(jì)算器中,行間距為15vp,列間距為10vp。
- Grid() {
- ...
- }
- .columnsGap(10)
- .rowsGap(15)
可滾動的網(wǎng)格布局常用在文件管理、購物或視頻列表等頁面中,如下圖所示。在設(shè)置Grid的行列數(shù)量與占比時,如果僅設(shè)置行、列數(shù)量與占比中的一個,即僅設(shè)置rowsTemplate或僅設(shè)置columnsTemplate屬性,網(wǎng)格單元按照設(shè)置的方向排列,超出Grid顯示區(qū)域后,Grid擁有可滾動能力。
如果設(shè)置的是columnsTemplate,Grid的滾動方向?yàn)榇怪狈较?;如果設(shè)置的是rowsTemplate,Grid的滾動方向?yàn)樗椒较颉?/p>
如上圖所示的橫向可滾動網(wǎng)格布局,只要設(shè)置rowsTemplate屬性的值且不設(shè)置columnsTemplate屬性,當(dāng)內(nèi)容超出Grid組件寬度時,Grid可橫向滾動進(jìn)行內(nèi)容展示。
- @Component
- struct Shopping {
- @State services: Array<string> = ['直播', '進(jìn)口', ...]
- ...
- build() {
- Column({ space: 5 }) {
- Grid() {
- ForEach(this.services, (service: string, index) => {
- GridItem() {
- ...
- }
- .width('25%')
- }, service => service)
- }
- .rowsTemplate('1fr 1fr') // 只設(shè)置rowsTemplate屬性,當(dāng)內(nèi)容超出Grid區(qū)域時,可水平滾動。
- .rowsGap(15)
- ...
- }
- ...
- }
- }
與新聞列表的返回頂部場景類似,控制滾動位置功能在網(wǎng)格布局中也很常用,例如下圖所示日歷的翻頁功能。
Grid組件初始化時,可以綁定一個Scroller對象,用于進(jìn)行滾動控制,例如通過Scroller對象的scrollPage方法進(jìn)行翻頁。
- private scroller: Scroller = new Scroller()
在日歷頁面中,用戶在點(diǎn)擊“下一頁”按鈕時,應(yīng)用響應(yīng)點(diǎn)擊事件,通過指定scrollPage方法的參數(shù)next為true,滾動到下一頁。
- Column({ space: 5 }) {
- Grid(this.scroller) {
- ...
- }
- .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')
- ...
- Row({space: 20}) {
- Button('上一頁')
- .onClick(() => {
- this.scroller.scrollPage({
- next: false
- })
- })
- Button('下一頁')
- .onClick(() => {
- this.scroller.scrollPage({
- next: true
- })
- })
- }
- }
- ...
與長列表的處理類似,循環(huán)渲染適用于數(shù)據(jù)量較小的布局場景,當(dāng)構(gòu)建具有大量網(wǎng)格項(xiàng)的可滾動網(wǎng)格布局時,推薦使用數(shù)據(jù)懶加載方式實(shí)現(xiàn)按需迭代加載數(shù)據(jù),從而提升列表性能。
關(guān)于按需加載優(yōu)化的具體實(shí)現(xiàn)可參考數(shù)據(jù)懶加載章節(jié)中的示例。
當(dāng)使用懶加載方式渲染網(wǎng)格時,為了更好的滾動體驗(yàn),減少滑動時出現(xiàn)白塊,Grid組件中也可通過cachedCount屬性設(shè)置GridItem的預(yù)加載數(shù)量,只在懶加載LazyForEach中生效。
- Grid() {
- LazyForEach(this.dataSource, item => {
- GridItem() {
- ...
- }
- })
- }
- .cachedCount(3)
cachedCount的增加會增大UI的CPU、內(nèi)存開銷。使用時需要根據(jù)實(shí)際情況,綜合性能和用戶體驗(yàn)進(jìn)行調(diào)整。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: