HarmonyOS NEXT星河版之模拟图片选择器(上)

一、目标

1895_1713431356

二、开撸

此文为模拟图片选择器,因此图片集合数据为mock。

2.1 声明数据

图库数据对象采用之前的商品列表,其中商品Item如下:

export interface GoodsItem {
  id: number,
  title: string
  imageUrl: string
}

选中后的图片对象封装,如下:

export interface SelectImageItem {
  id: number
  imgUrl: string
}

2.2 mock数据

mock图片列表,使用其中的图片资源,如下:

export const mockGoodsList: GoodsItem[] = [
  {
    id: 1,
    title: '宁雨昔美式复古字母三条杠圆领短袖T恤女纯棉宽松2024夏季新款学生上衣 白色 M',
    imageUrl: 'https://img10.360buyimg.com/n2/s240x240_jfs/t1/145307/22/41197/71267/65b5d932Fb67b2c27/cd986ae610999146.jpg!q70.jpg.webp'
  },
  {
    id: 2,
    title: '京东京造【抗菌小白T】5A抑菌抗发黄T恤男新疆棉t恤男夏短袖打底T 白色L',
    imageUrl: 'https://img10.360buyimg.com/n2/s370x370_jfs/t1/230742/32/2823/51634/65520517F4c4f8ffb/6b8d81f6664085c6.jpg!q70.jpg.webp'
  },
  {
    id: 3,
    title: 'YOOOURTHING男士休闲夹克青年时尚休闲连帽外套男薄款春秋季夹克男装 XZ1402-2130-卡其色 2XL【建议120-150斤】',
    imageUrl: 'https://img13.360buyimg.com/n2/s370x370_jfs/t1/100084/4/36774/78306/6423d6a8F913e76ad/80a8cdf35c09e19c.jpg!q70.jpg.webp'
  },
  {
    id: 4,
    title: 'ZARA女装夏季新款宽松短袖T恤女 黑色 M',
    imageUrl: 'https://img10.360buyimg.com/n2/s370x370_jfs/t1/134131/23/44409/75625/661c013dF4a6fba04/3166211e54969778.jpg!q70.jpg.webp'
  },
  {
    id: 5,
    title: '优衣库UT印花T恤女款 纯棉舒适圆领短袖上衣 白色 S',
    imageUrl: 'https://img14.360buyimg.com/n2/s370x370_jfs/t1/103976/1/31353/115998/630cc1cdE3a4eede9/bc1bc0bc560b775e.jpg!q70.jpg.webp'
  },
  {
    id: 6,
    title: '小米手环5 智能运动手表 血氧检测心率监测 多功能NFC 时尚简约 黑色',
    imageUrl: 'https://img14.360buyimg.com/n2/s370x370_jfs/t1/100923/8/44254/52554/64f03948Fe911c342/59bea895f9ebdd38.jpg!q70.jpg.webp'
  },
  {
    id: 7,
    title: '华为荣耀X10 5G手机 双模5G全网通 6GB+128GB 蓝水翡翠 移动联通电信5G 双卡双待手机',
    imageUrl: 'https://img0.baidu.com/it/u=2707221971,2703286647&fm=253&fmt=auto&app=138&f=JPEG?w=499&h=287'
  },
  {
    id: 8,
    title: 'Apple MacBook Air 13.3英寸笔记本电脑 银色(Core i5 处理器/8GB内存/256GB固态硬盘)',
    imageUrl: 'https://img01.yzcdn.cn/upload_files/2020/05/21/FjX6bDV0pc4jSBKXgbDcDvtErMzR.jpg%21middle.jpg'
  },
  {
    id: 9,
    title: '华为MateBook D 14 2020款 14英寸轻薄笔记本电脑(AMD Ryzen 5 3500U处理器/8GB内存/512GB固态硬盘)深空灰',
    imageUrl: 'https://img01.yzcdn.cn/upload_files/2017/10/19/FlYiuiKI5L17wHoALIx_txbCeOME.jpg%21middle.jpg'
  },
  {
    id: 10,
    title: '联想(Lenovo)小新Pro13高性能轻薄本笔记本电脑 13.3英寸全面屏学生办公商务便携轻薄本(标压R5-3550H 16G 512G FHD IPS)银',
    imageUrl: 'https://img2.baidu.com/it/u=1282939547,1976310423&fm=253&fmt=auto&app=138&f=JPEG?w=375&h=500'
  }

]

2.3 封装图片选择器View

import { GoodsItem, mockGoodsList } from '../../waterflow/modules'
import { SelectImageItem } from '../models'
import { promptAction } from '@kit.ArkUI'

@Component
struct PhotoAlbumView {
  // 图片列表,此处为模拟数据
  goodsList: GoodsItem[] = mockGoodsList
  // 最大选择数
  maxNumber: number = 3
  // 已选择的图片
  @State selectImgList: SelectImageItem[] = []
  // 取消回调
  cancel: () => void = () => {
  }
  // 确定回调
  confirm: (selectImgList: SelectImageItem[]) => void = () => {
  }

  // 图片点击  选中or取消选择
  onItemClick(item: GoodsItem) {
    const index = this.judgeItemIsSelected(item)
    if (index > -1) {
      // 当前已选列表中有该Item,删除
      this.selectImgList.splice(index, 1)
    } else {
      // 已选择列表中没有当前Item,在判断可选数量是否已超
      if (this.selectImgList.length < this.maxNumber) {
        this.selectImgList.push({ id: item.id, imgUrl: item.imageUrl })
      }
    }
  }

  judgeItemIsSelected(item: GoodsItem) {
    return this.selectImgList.findIndex(obj => obj.id === item.id)
  }

  build() {
    Column() {
      Grid() {
        ForEach(this.goodsList, (item: GoodsItem) => {
          GridItem() {
            Stack() {
              Image(item.imageUrl)
                .aspectRatio(1)
              if (this.judgeItemIsSelected(item) > -1) {
                Image($r('app.media.ic_selected'))
                  .width(24)
                  .fillColor(Color.Red)
              }
            }
            .onClick(() => {
              this.onItemClick(item)
            })
          }
        }, (item: GoodsItem) => JSON.stringify(item))
      }
      .columnsTemplate('1fr 1fr 1fr')
      .columnsGap(5)
      .rowsGap(5)
      .padding(10)
      .layoutWeight(1)

      Row() {
        Button('取消')
          .width(68)
          .height(32)
          .backgroundColor(Color.Grey)
          .onClick(() => {
            this.cancel()
          })
        Text(`已选${this.selectImgList.length}张/总计${this.maxNumber}`)
        Button('确定')
          .width(68)
          .height(32)
          .onClick(() => {
            this.confirm(this.selectImgList)
          })
      }
      .justifyContent(FlexAlign.SpaceAround)
      .width('100%')
      .height(48)
      .backgroundColor(Color.Pink)
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.White)
    .position({ x: 0, y: 0 })
  }
}

export { PhotoAlbumView }

2.4 主页面

import { PhotoAlbumView } from './components/PhotoAlbumView';
import { SelectImageItem } from './models';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct PhotoAlbumDemoPage {
  @State message: string = 'Hello World';
  @State showPhotoAlbum: boolean = false
  @State selectImgList: SelectImageItem[] = []

  build() {
    Column() {
      Button('打开相册')
        .onClick(() => {
          this.showPhotoAlbum = true
        })
      Text('已选择图片:')
        .width('100%')
        .textAlign(TextAlign.Start)
      if (this.selectImgList && this.selectImgList.length) {
        Grid() {
          ForEach(this.selectImgList, (item: SelectImageItem) => {
            GridItem() {
              Stack() {
                Image(item.imgUrl)
                  .aspectRatio(1)
                  .onClick(() => {
                    promptAction.showToast({ message: '预览功能,待完善' })
                  })
              }
            }
          }, (item: SelectImageItem) => JSON.stringify(item))
        }
        .columnsTemplate('1fr 1fr 1fr')
        .columnsGap(5)
        .rowsGap(5)
        .padding(10)
        .layoutWeight(1)
      }
      if (this.showPhotoAlbum) {
        PhotoAlbumView({
          maxNumber: 5,
          cancel: () => {
            this.showPhotoAlbum = false
          },
          confirm: (selectImgList: SelectImageItem[]) => {
            this.showPhotoAlbum = false
            this.selectImgList = [...this.selectImgList, ...selectImgList]
          }
        })
      }
    }
    .width('100%')
    .height('100%')
  }
}

三、小结

  • 图片选择模拟器列表组件封装
  • 图片选中、取消选择处理
  • 选中的图片列表回调主页面
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值