HarmonyOS ArkUI之仿微信图片选择 原创 精华
作者:梁青松
前言
本项目就是基于ArkUI中的声明式编程开发,语言ETS(Extended Type Script),代码都在ets文件中编写,这个文件用于描述 UI 布局、样式、事件交互和页面逻辑。
官方文档地址:基于TS扩展的声明式开发范式1 基于TS扩展的声明式开发范式2
前文回顾【HarmonyOS ArkUI之仿微信朋友圈图片预览】仿微信朋友圈实现列表展示,九宫格小图图片展示,点击图片进行图片预览,图片左右滑动切换。
本文介绍仿照微信选择图片、多选图片、点击浏览大图,删除选择的图片,因为用的ets语言开发,为了方便演示,图片数据没有获取手机本地图片,使用内置资源。
效果演示
项目类说明
主要知识点
九宫格列表和选择图片列表:网格容器组件(Grid)
浏览大图切换页面:滑动容器组件(Swiper)
循环渲染迭代数组:渲染组件(ForEach) (目前第二个参数中 itemGenerator: (item: any, index?: number) => void index不能使用)
基础的组件:图片显示(Image) 文本显示(Text) 按钮(Button)
代码解析
1、图片列表
主要是网格容器Grid组件和渲染组件ForEach,注释也很清楚,让你更快掌握知识点。(简单示例)
@Entry
@Component
struct Test {
@State private listPicture: Array<Resource> = [
$r("app.media.ic_picture1"), $r("app.media.ic_picture2"), $r("app.media.ic_picture3"),
$r("app.media.ic_picture4"), $r("app.media.ic_picture5"), $r("app.media.ic_picture6"),
$r("app.media.ic_picture7"), $r("app.media.ic_picture8"), $r("app.media.ic_picture9"),
$r("app.media.ic_picture10"), $r("app.media.ic_picture11"), $r("app.media.ic_picture12")
]
build() {
Column() {
// 网格图片列表
Grid() {
ForEach(this.listPicture, item => {
GridItem() {
// 图片
Image(item)
.width('100%')
.height(90)
.objectFit(ImageFit.Cover) // 缩放类型
}
}, item => item.toString()) // ForEach第三个参数需要设置,否则模拟器不显示
}.columnsTemplate('1fr 1fr 1fr 1fr') // 4等分列
.columnsGap(2) // 列间距
.rowsGap(2) // 行间距
}
.width('100%')
.height('100%')
}
}
2、点击选择框
处理选中和未选中效果,主要点击当前项时,根据选中状态进行替换列表中的对象,设置按钮的文字和启用状态,框架会自动更新界面。(项目中部分代码)
......
/**
* 点击是否选中
*/
clickIsSelected(item:PictureData) {
// 点击未选中 且 选中数大于总数,则返回
if (!item.isSelected && this.listSelectPicture.length >= this.total) {
return
}
//全部列表:替换元素、更新选中状态
let newItem = {
id: item.id,
picResource: item.picResource,
isSelected: !item.isSelected
}
this.listAllPicture.splice(item.id, 1, newItem)
//选中的列表:选中就添加,未选中删除
if (newItem.isSelected) {
this.listSelectPicture.push(item.picResource)
} else {
let index = this.listSelectPicture.indexOf(item.picResource)
this.listSelectPicture.splice(index, 1)
}
// 根据选中的数量,显示按钮状态和文字
this.isEnabledComplete = this.listSelectPicture.length != 0
if(this.listSelectPicture.length == 0){
this.completeText = '完成';
}else{
this.completeText = `完成(${this.listSelectPicture.length}/${this.total})`;
}
}
......
3、显示选中的图片
需要注意的点:根据选择的图片总数,显示或隐藏添加按钮。(项目中部分代码)
......
/**
* 在build函数之前执行
*/
private aboutToAppear() {
// 首次进入显示添加按钮
let showAddData = new HomePictureData(-1, $r('app.media.ic_add'), true)
this.listPicture.push(showAddData)
}
/**
* 页面显示触发
*/
private onPageShow() {
try {
let list: Array<Resource> = router.getParams().listSelectPicture
// 存入图片
for (let listKey of list) {
this.listSelectPicture.push(listKey)
}
// 清空旧数据
this.listPicture = []
// 添加新的数据,存入id
for (var i = 0;i < this.listSelectPicture.length; i++) {
let resource = this.listSelectPicture[i]
this.listPicture.push(new HomePictureData(i, resource, false))
}
// 判断是否小于总数,设置最后一位显示加号
if (this.listSelectPicture.length < this.total) {
let showAddData = new HomePictureData(-1, $r('app.media.ic_add'), true)
this.listPicture.push(showAddData)
}
} catch (err) {
console.log(`router错误 code: ${err.code}, msg: ${err.msg}`)
}
}
......
4、浏览大图
主要使用滑动容器组件Swiper,根据上个页面传的操作值:是否删除、显示删除按钮。(简单示例)
@Entry
@Component
struct Test {
@State private listPicture: Array<Resource> = [
$r("app.media.ic_picture1"), $r("app.media.ic_picture2"), $r("app.media.ic_picture3"),
$r("app.media.ic_picture4"), $r("app.media.ic_picture5"), $r("app.media.ic_picture6"),
$r("app.media.ic_picture7"), $r("app.media.ic_picture8"), $r("app.media.ic_picture9"),
$r("app.media.ic_picture10"), $r("app.media.ic_picture11"), $r("app.media.ic_picture12")
]
@State imageIndex:number = 0
build() {
Column() {
// 切换页面
Swiper() {
ForEach(this.listPicture, item => {
// 图片
Image(item)
.width('100%')
.height('100%')
.objectFit(ImageFit.Cover) //缩放类型
}, item => item.toString())
}
.width('100%')
.height('100%')
.index(this.imageIndex)// 设置当前索引
.indicator(false)// 不显示指示器
.loop(false) // 关闭循环
.onChange((index: number) => {// 索引变化监听
// 更新索引值
this.imageIndex = index
})
}
.width('100%')
.height('100%')
}
}
项目地址
https://gitee.com/liangdidi/PictureSelectionDemo.git(需要登录才能看到演示图)
更多原创内容请关注:开鸿 HarmonyOS 学院
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,共建鸿蒙生态,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
楼主在彷微信的路上越走越远,支持一波。
哈哈哈,好像可以把文章凑一凑,做一个类似于的聊天软件demo了