# PictureSelectionDemo **Repository Path**: lianghao_721/PictureSelectionDemo ## Basic Information - **Project Name**: PictureSelectionDemo - **Description**: 图片选择 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-10-28 - **Last Updated**: 2021-10-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 基于ArkUI构建出仿微信九宫格选择图片 ### 前言 新世界的大门已打开,关也关不住! 《华为开发者大会2021》推出了方舟开发框架(ArkUI),官方解释:方舟开发框架是一种跨设备的高性能UI开发框架,支持声明式编程和跨设备多态UI。 本项目就是基于ArkUI中的声明式编程开发,语言ETS(Extended Type Script),代码都在ets文件中编写,这个文件用于描述 UI 布局、样式、事件交互和页面逻辑。 官方文档地址:[基于TS扩展的声明式开发范式1](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-ts-overview-0000001192705715) [基于TS扩展的声明式开发范式2](https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-framework-directory-0000001111581264) ### 项目说明 本项目仿照微信选择图片、多选图片、点击浏览大图,删除选择的图片,因为用的ets语言开发,为了方便演示,图片数据没有获取手机本地图片,使用内置资源。 ### 效果演示图 ![](image/demo.gif) ### 主要知识点 九宫格列表和选择图片列表:[网格容器组件(Grid)](https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-container-grid-0000001158261259) 浏览大图切换页面:[滑动容器组件(Swiper)](https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-container-swiper-0000001111421434) 循环渲染迭代数组:[渲染组件(ForEach)](https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-rending-control-syntax-foreach-0000001149978669) (目前第二个参数中 itemGenerator: (item: any, index?: number) => void **index不能使用**) 基础的组件:[图片显示(Image)](https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-basic-components-image-0000001111581276) [文本显示(Text)](https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-basic-components-text-0000001111581280) [按钮(Button)](https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-basic-components-button-0000001158141265) ### 代码解析 #### 1、图片列表 主要是网格容器Grid组件和渲染组件ForEach,注释也很清楚,让你更快掌握知识点。**(简单示例)** ```tsx @Entry @Component struct Test { @State private listPicture: Array = [ $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、点击选择框 处理选中和未选中效果,主要点击当前项时,根据选中状态进行替换列表中的对象,设置按钮的文字和启用状态,框架会自动更新界面。**(项目中部分代码)** ![](image/demo1.jpg) ```tsx ...... /** * 点击是否选中 */ 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、显示选中的图片 需要注意的点:根据选择的图片总数,显示或隐藏添加按钮。**(项目中部分代码)** ![](image/demo2.jpg)![](image/demo3.jpg) ```tsx ...... /** * 在build函数之前执行 */ private aboutToAppear() { // 首次进入显示添加按钮 let showAddData = new HomePictureData(-1, $r('app.media.ic_add'), true) this.listPicture.push(showAddData) } /** * 页面显示触发 */ private onPageShow() { try { let list: Array = 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,根据上个页面传的操作值:是否删除、显示删除按钮。**(简单示例)** ![](image/demo4.jpg)![](image/demo5.jpg) ```tsx @Entry @Component struct Test { @State private listPicture: Array = [ $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%') } } ``` ### 项目类说明 ![](image/demo6.jpg) ### 项目地址 [https://gitee.com/liangdidi/PictureSelectionDemo.git](https://gitee.com/liangdidi/PictureSelectionDemo.git)(需要登录才能看到演示图) ### 结尾 之前javaUI、jsUI都研究过,也都写过对应的项目。现在新的声明式UI上手后,真的快!!!希望快快完善API,早日可以做完整的大项目。 ### 版权和许可信息 ``` Copyright [2021] [liangqingsong of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ```