HarmonyOS-选择发布9宫格图片

选择图片主要设计到状态管理,鸿蒙中状态管理是比较复杂而且又是必备技能,先看效果图:


preview.gif

首先定义图片数据实体类:

interface ILocalImgData {image: ResourceStr}

class LocalImgData implements ILocalImgData {
  image: ResourceStr

  constructor(data: ILocalImgData) {
    this.image = data.image
  }
}

export { LocalImgData, ILocalImgData }

SelectImagePage

@Entry
@Component
struct SelectImagePage {
  @State
  isShowSelectSheet: boolean = false
  @State
  selected: ILocalImgData[] = []
  maxNum: number = 9

  @Builder
  ImageSelectBuilder() {
Column() {
  SelectImageSheet({
    maxSelectNum: this.maxNum - this.selected.length,
    selected: this.selected,
    isShowSelectSheet: this.isShowSelectSheet
  })
}
  }

  build() {
Grid() {
  ForEach(this.selected, (item: ILocalImgData) => {
    GridItem() {
      Stack({ alignContent: Alignment.TopEnd }) {
        Image(item.image)
          .width("100%")
          .aspectRatio(1)
          .borderRadius(6)
        Image($r("app.media.delete"))
          .width(16)
          .aspectRatio(1)
          .margin(10)
          .onClick(() => {
            this.selected = this.selected.filter((fItem) => fItem != item)
          })
      }.width("100%")
    }
  })
  GridItem() {
    Image($r("app.media.add")).width(16).aspectRatio(1)
  }.border({ width: 1, color: Color.Gray, radius: 6 })
  .aspectRatio(1)
  .visibility(this.maxNum - this.selected.length == 0 ? Visibility.None : Visibility.Visible)
  .onClick(() => this.isShowSelectSheet = true)
}
.columnsTemplate("1fr 1fr 1fr")
.columnsGap(6)
.rowsGap(6)
.height('100%')
.width('100%')
.padding({
  top: 10 + px2vp(AppManager.topSafeHeight),
  bottom: px2vp(AppManager.topSafeHeight),
  left: 10,
  right: 10
})
.bindSheet($$this.isShowSelectSheet,
  this.ImageSelectBuilder(), {
    height: "80%",
    enableOutsideInteractive: true,
    showClose: false
  })
  }
}
SelectImageSheet
@Component
struct SelectImageSheet {
private imageResources: ILocalImgData[] = [................]
@State
selectImages: ILocalImgData[] = []
@Link
selected: ILocalImgData[]
@Link
isShowSelectSheet: boolean
maxSelectNum: number = 9

build() {
Column() {
  Row() {
    Text("取消")
      .fontSize(16)
      .onClick(() => this.isShowSelectSheet = false)
    Text(`${this.selectImages.length}/${this.maxSelectNum}`)
      .fontSize(16)
    Text("确定")
      .fontSize(16)
      .onClick(() => {
        this.selected.unshift(...this.selectImages)
        this.isShowSelectSheet = false
      })
  }
  .padding(20)
  .justifyContent(FlexAlign.SpaceBetween)
  .width('100%')

  Grid() {
    ForEach(this.imageResources, (item: ILocalImgData) => {
      GridItem() {
        Stack({ alignContent: Alignment.BottomEnd }) {
          Image(item.image).width("100%").aspectRatio(1)
            .borderRadius(6)
          Image($r("app.media.select"))
            .width(16)
            .aspectRatio(1)
            .margin(10)
            .visibility(this.selectImages.includes(item) ? Visibility.Visible : Visibility.None)
        }.width("100%")
      }.onClick(() => {
        console.log("TAG>>>" + JSON.stringify(this.selectImages))
        if (this.selectImages.includes(item)) {
          this.selectImages = this.selectImages.filter((fItem) => fItem != item)
          return
        }
        if (this.selectImages.length >= this.maxSelectNum) {
          promptAction.showToast({ message: `最多只能选中${this.maxSelectNum}` })
          return
        }
        this.selectImages.unshift(item)
      })
    })
  }
  .columnsTemplate("1fr 1fr 1fr")
  .columnsGap(6)
  .rowsGap(6)
  .padding({ left: 20, right: 20 })
  .height('100%')
  .width('100%')
}
}
}

export default SelectImageSheet

图片预览

@CustomDialog
struct PreviewImageDialog {
controller: CustomDialogController
@Link
currentIndex: number
@Link
previewImages: ILocalImgData[]

build() {
Column() {
  Stack({ alignContent: Alignment.Bottom | Alignment.Center }) {
    Swiper() {
      ForEach(this.previewImages, (item: ILocalImgData) => {
        Image(item.image)
          .width("100%")
      })
    }.index($$this.currentIndex)
    .autoPlay(true)
    .indicator(false)

    Text(`${this.currentIndex + 1}/${this.previewImages.length}`)
      .margin(10)
      .fontColor(Color.White)
      .fontSize(16)
  }
}
.justifyContent(FlexAlign.Center)
.backdropBlur(30)
.width("100%")
.height("100%")
.onClick(() => {
  this.controller.close()
})
  }
}

export default PreviewImageDialog
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容