純血鴻蒙APP實(shí)戰(zhàn)開(kāi)發(fā)——圖片九宮格封裝案例

介紹

本示例介紹使用( Flex )組件實(shí)現(xiàn)圖片在不同個(gè)數(shù)情況下的布局效果(默認(rèn)布局和自定義布局)。該場(chǎng)景多用于社交類應(yīng)用。

效果圖預(yù)覽

使用說(shuō)明

  1. 默認(rèn)布局情況下,傳入圖片資源imageSource(類型為Resource[]),圖片會(huì)按照個(gè)數(shù)進(jìn)行相應(yīng)的布局。
  2. 自定義布局情況下,傳入圖片資源imageSource(類型為Resource[])和自定義列數(shù)col(類型為number)。
  3. 通過(guò)指定flexWidth(類型為string)參數(shù),可調(diào)整整個(gè)圖片布局的寬度。
  4. 通過(guò)指定modifier(類型需繼承AttributeModifier<ImageAttribute> )參數(shù),可以指定image的相關(guān)參數(shù),modifier具體使用參考動(dòng)態(tài)屬性設(shè)置。

默認(rèn)布局策略:

  • 1張圖片時(shí),圖片顯示效果的長(zhǎng)寬比保持不變。
  • 2-3,5-9張圖片時(shí),圖片按九宮格的形式布局,圖片裁切為正方形,且圖片大小一致.
  • 4張圖片時(shí),圖片按四宮格布局(兩行兩列),圖片大小同九宮格。

實(shí)現(xiàn)思路

本例中代碼詳情可參考ImageGridLayout.ets
MultiGrid.ets

1.在自定義組件創(chuàng)建的回調(diào)里根據(jù)傳入的col值決定布局方式,若參數(shù)col<=0為默認(rèn)布局,若參數(shù)col>0為自定義布局(圖片布局的列數(shù)=col),
此部分邏輯會(huì)根據(jù)傳入?yún)?shù)的不同走不同的邏輯。

aboutToAppear(){
  this.arraySize = this.imageSource.length
  // 未傳入col值時(shí)所走的邏輯,此時(shí)圖片按默認(rèn)方式布局
  if (this.col <= COLUMNS_0) {
    this.arraySize = Math.min(this.imageSource.length, IMAGE_SET_SIZE_9)
    this.row = Math.ceil(this.arraySize / COLUMNS_3)

    // 不同數(shù)量的圖片對(duì)應(yīng)不同的參數(shù)、布局
    if (this.arraySize === IMAGE_SET_SIZE_1) {
      this.col = COLUMNS_1
      this.imageAspectRatio = IMAGE_ASPECT_RATIO_0
      this.imageFit = ImageFit.Contain
      this.imageWidth = '60%'
    }
    else if (this.arraySize === IMAGE_SET_SIZE_4) {
      this.col = COLUMNS_2
      this.flexWidth = '50%'
      this.imageWidth = `calc((100% - ${this.imageSpacing}vp ) / 2)`
    }
    else {
      this.col = COLUMNS_3
      this.imageWidth = `calc((100% - ${this.imageSpacing * COLUMNS_2}vp ) / 3)`
    }
  }
  // 傳入col值時(shí)所走的邏輯,此時(shí)圖片傳入的col值進(jìn)行布局
  else {
    this.row = Math.ceil(this.arraySize / this.col)
    this.imageWidth = `calc((100% - ${this.imageSpacing * (this.col - 1)}vp ) / ${this.col})`
  }

}

2.布局主要是利用Flex的自適應(yīng)能力及控制參數(shù)的變化來(lái)達(dá)到想要的布局效果。

build(){
  Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Start }){
    ForEach(this.imageSource.slice(0, this.arraySize), (item: string | Resource, idx: number) => {
      Image(item)
        .attributeModifier(this.modifier)
        .autoResize(true)
        .objectFit(this.imageFit)
        .aspectRatio(this.imageAspectRatio)
        .width(this.imageWidth)
        .margin(
          {
            bottom: (idx + 1) > ((this.row - 1) * this.col) ? 0 : this.imageSpacing,
            right: (idx + 1) % this.col === 0 ? 0 : this.imageSpacing
          }
        )
    })
  }
  .width(this.flexWidth)
}

3.為image組件指定特定的參數(shù)可實(shí)現(xiàn)AttributeModifier<ImageAttribute>的繼承類,聲明想要的屬性并實(shí)現(xiàn)對(duì)應(yīng)的方法。繼承類及使用的代碼如下

// 圖片屬性的modifier類,便于用戶擴(kuò)展image相關(guān)的屬性
class ImageModifier implements AttributeModifier<ImageAttribute> {
  private imageFit: ImageFit = ImageFit.Fill;
  private imageRenderMode: ImageRenderMode = ImageRenderMode.Original;

  constructor() {
  }

  applyNormalAttribute(instance: ImageAttribute): void {
    instance.objectFit(this.imageFit)
    instance.renderMode(this.imageRenderMode)
  }

  objectFit(fit: ImageFit): ImageModifier {
    this.imageFit = fit;
    return this;
  }

  renderMode(mode: ImageRenderMode): ImageModifier {
    this.imageRenderMode = mode;
    return this;
  }
}
···
private imageModifier: ImageModifier = new ImageModifier().objectFit(ImageFit.Fill)
  .renderMode(ImageRenderMode.Original)
···
MultiGrid({ imageSource: item, modifier: this.imageModifier })

高性能知識(shí)點(diǎn)

不涉及

工程結(jié)構(gòu)&模塊類型

imagegridlayout                             // har類型
|---src/main/ets/components/mainpage
|   |---ImageGridLayout.ets                 // 圖片九宮格展示實(shí)現(xiàn)頁(yè)面
|   |---MultiGrid.ets                       // 圖片九宮格案例封裝

寫(xiě)在最后

如果你覺(jué)得這篇內(nèi)容對(duì)你還蠻有幫助,我想邀請(qǐng)你幫我三個(gè)小忙

  • 點(diǎn)贊,轉(zhuǎn)發(fā),有你們的 『點(diǎn)贊和評(píng)論』,才是我創(chuàng)造的動(dòng)力。
  • 關(guān)注小編,同時(shí)可以期待后續(xù)文章ing??,不定期分享原創(chuàng)知識(shí)。
  • 想要獲取更多完整鴻蒙最新學(xué)習(xí)知識(shí)點(diǎn),請(qǐng)移步前往小編:https://gitee.com/MNxiaona/733GH/blob/master/jianshu
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容