往期鸿蒙全套实战文章必看:
使用PhotoPicker组件访问图片/视频
当应用需要读取用户图片时,开发者可以在应用界面中嵌入PhotoPicker组件,在用户选择所需要的图片资源后,直接返回该图片资源,而不需要授予应用读取图片文件的权限,即可完成图片或视频文件的访问和读取。
界面效果如图所示。
宫格页 | 大图页 |
| |
开发步骤
- 导入PhotoPicker模块文件。
import { PhotoPickerComponent, PickerController, PickerOptions, DataType, ItemInfo, ItemType, PhotoBrowserInfo, ClickType, PickerColorMode, MaxSelected, MaxCountType, ReminderMode, PickerOrientation, BaseItemInfo, PhotoBrowserRange, } from '@ohos.file.PhotoPickerComponent'; import photoAccessHelper from '@ohos.file.photoAccessHelper';
- 创建Picker组件配置选项实例(PickerOptions)和控制实例(PickerController)。
通过PickerOptions,开发者可配置Picker宫格的样式(如勾选框背景色、文本颜色等)、滑动预览方向、最大选择数量等参数。
通过PickerController,应用可向Picker组件发送数据。
// 组件初始化时设置参数信息 pickerOptions: PickerOptions = new PickerOptions(); // 组件初始化完成后,可控制组件部分行为 @State pickerController: PickerController = new PickerController();
- 应用界面出现时,初始化组件配置选项实例(PickerOptions)。此处仅列举部分参数。
aboutToAppear() { // 设置picker宫格页数据类型 this.pickerOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE; // 是否展示搜索框,默认false this.pickerOptions.isSearchSupported = true; // 是否支持拍照,默认false this.pickerOptions.isPhotoTakingSupported = true; // 是否支持重复选择 this.pickerOptions.isRepeatSelectSupported = false; // 最大选择数量 this.pickerOptions.maxSelectNumber = 8; // 最大选择数量 // 最大图片选择数量 this.pickerOptions.maxPhotoSelectNumber = 8; // 最大图片选择数量 // 最大视频选择数量 this.pickerOptions.maxVideoSelectNumber = 8; // 最大视频选择数量 // 超出最大选择数量时 this.pickerOptions.maxSelectedReminderMode = ReminderMode.TOAST; // 设置大图背景色 this.pickerOptions.photoBrowserBackgroundColorMode = PickerColorMode.AUTO; // 设置checkbox选中颜色 this.pickerOptions.checkBoxColor = '#000000'; // 设置checkbox文字颜色 this.pickerOptions.checkboxTextColor = '#000000'; // 设置宫格页背景色 this.pickerOptions.backgroundColor = '#000000'; // 设置选择模式,默认:MULTI_SELECT this.pickerOptions.selectMode = SelectMode.SINGLE_SELECT; }
- 实现回调函数。
通过实现以下回调事件,可在用户在界面操作时,将相关信息报给应用进行处理。
- 进退大图、切换大图回调。
- 勾选或取消勾选图片/视频,将上报图片URI供应用使用。
说明
- 点击图片(缩略图item),将上报图片/视频信息ItemInfo;点击相机item,可拉起系统相机或应用自行处理。
// 进入大图页回调 private onEnterPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean { console.info('onEnterPhotoBrowser' + JSON.stringify(photoBrowserInfo)); return false; } // 退出大图页回调 private onExitPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean { console.info('onExitPhotoBrowser' + JSON.stringify(photoBrowserInfo)); return false; } // 接收到该回调后,便可通过pickerController相关接口向picker发送数据,在此之前不生效。 private onPickerControllerReady(): void { console.info('onPickerControllerReady'); } // 大图页图片切换回调事件处理 private onPhotoBrowserChanged(photoBrowserItemInfo: BaseItemInfo): boolean { console.info('onPhotoBrowserChanged' + JSON.stringify(photoBrowserItemInfo)); this.currentUri = photoBrowserItemInfo.uri ?? ''; return true; } // 图片/视频被选中的回调,返回的url只有只读权限,不能用url直接去打开 private onSelect(uri: string): void { if (uri) { this.selectedUris.push(uri) } // 将uri保存起来,并保证切换不同的宫格页组件时保持选中项一致 this.pickerOptions.preselectedUris = [...this.selectedUris]; this.pickerOptions1.preselectedUris = [...this.selectedUris]; this.pickerOptions2.preselectedUris = [...this.selectedUris]; console.info('onSelect' + JSON.stringify(this.selectedUris)); } // 图片/视频被取消勾选的回调,返回的url只有只读权限,不能用url直接去打开 private onDeselect(uri: string): void { if (uri) { this.selectedUris = this.selectedUris.filter((item: string) => { return item !== uri; }) } // 排除反勾选uri,并保证切换不同的宫格页组件时保持选中项一致 this.pickerOptions.preselectedUris = [...this.selectedUris]; this.pickerOptions1.preselectedUris = [...this.selectedUris]; this.pickerOptions2.preselectedUris = [...this.selectedUris]; console.info('onDeselect' + JSON.stringify(this.selectedUris)); } /** * 图片/视频被选中回调,返回资源的信息,以及选中方式 * ItemInfo 图片、视频相关信息 * ClickType(SELECTED:勾选, DESELECTED: 反选) * return 返回值为true时才会给url授权(返回的uri权限是只读权限) */ private onItemClicked(itemInfo: ItemInfo, clickType: ClickType): boolean { if (!itemInfo) { return false; } let type: ItemType | undefined = itemInfo.itemType; let uri: string | undefined = itemInfo.uri; if (type === ItemType.CAMERA) { // 点击相机item console.info('onCameraClick'); if (this.isBlock) { return false; } // 返回true则拉起系统相机,若应用需要自行处理则返回false。 return true; } else if (type === ItemType.THUMBNAIL) { //点击图片、视频item(缩略图item) if (clickType === ClickType.SELECTED) { //选中 if (this.isBlock) { return false; } // 将uri保存起来,并保证切换不同的宫格页组件时保持选中项一致 if (uri) { this.selectedUris.push(uri) this.pickerOptions.preselectedUris = [...this.selectedUris]; this.pickerOptions1.preselectedUris = [...this.selectedUris]; this.pickerOptions2.preselectedUris = [...this.selectedUris]; } } else { //反选 if (uri) { // 排除反勾选uri,并保证切换不同的宫格页组件时保持选中项一致 this.selectedUris = this.selectedUris.filter((item: string) => { return item !== uri; }) this.pickerOptions.preselectedUris = [...this.selectedUris]; this.pickerOptions1.preselectedUris = [...this.selectedUris]; this.pickerOptions2.preselectedUris = [...this.selectedUris]; } } } else { } console.info('onItemClicked' + JSON.stringify(itemInfo)); return true; }
- 创建PhotoPickerComponent组件。
build() { PhotoPickerComponent({ // 设置组件选择选项实例 pickerOptions: this.pickerOptions, // 资源被选中回调,返回url信息(返回的uri权限是只读权限) onSelect: (uri: string): void => this.onSelect(uri), // 资源被反选回调,返回url信息(返回的uri权限是只读权限) onDeselect: (uri: string): void => this.onDeselect(uri), /** * 资源被选中回调,返回资源的信息,以及选中方式 * ItemInfo(itemType, uri, mimeType, width, height, size, duration) * ClickType(SELECTED:勾选, DESELECTED: 反选) * return 返回值为true时才会给url授权(返回的uri权限是只读权限) */ onItemClicked: (itemInfo: ItemInfo, clickType: ClickType): boolean => this.onItemClicked(itemInfo, clickType), /** * 进入大图页回调, * PhotoBrowserInfo (animatorParams: 动效) */ onEnterPhotoBrowser: (photoBrowserInfo: PhotoBrowserInfo): boolean => this.onEnterPhotoBrowser(photoBrowserInfo), /** * 退出大图页回调, * PhotoBrowserInfo (animatorParams: 动效) */ onExitPhotoBrowser: (photoBrowserInfo: PhotoBrowserInfo): boolean => this.onExitPhotoBrowser(photoBrowserInfo), /** * 切换大图页内容回调事件, * PhotoBrowserInfo (animatorParams: 动效) */ onPhotoBrowserChanged: (photoBrowserItemInfo: BaseItemInfo): boolean => this.onPhotoBrowserChanged(photoBrowserItemInfo), // 接收到该回调后,便可通过pickerController相关接口向picker发送数据,在此之前不生效。 onPickerControllerReady: (): void => this.onPickerControllerReady(), // picker控制实例,应用可通过PickerController向picker组件发送数据,实现控制PhotoPickerComponent组件行为 pickerController: this.pickerController, }) }
- 通过PickerController向Picker组件发送数据,实现控制PhotoPickerComponent组件行为。
存在多种用法。
使用PickerController
- 用法1:通过相册URI,设置PhotoPickerComponent组件宫格页展示的相册的图片。
private onAlbumClick(albumInfo: AlbumInfo): boolean { this.isShowAlbum = false; console.info('onAlbumClick' + JSON.stringify(albumInfo?.uri)); if (albumInfo?.uri) { this.pickerController.setData(DataType.SET_ALBUM_URI, albumInfo.uri); console.info('onAlbumClick' + JSON.stringify(albumInfo.uri)); } return true; } }
- 用法2:设置PhotoPickerComponent组件宫格页选中的图片。
this.pickerController.setData(DataType.SET_SELECTED_URIS, this.selectedUris);
- 用法3:设置PhotoPickerComponent组件宫格页最大选择(总数/图片/视频)的数量。此处使用一个Button组件方便验证,开发者可根据实际诉求实现。
Button("设置选择数量").width('50%').height('5%').onClick(() => { let maxSelect: MaxSelected = new MaxSelected(); maxSelect.data = new Map<MaxCountType, number>([[MaxCountType.TOTAL_MAX_COUNT, 10], [MaxCountType.PHOTO_MAX_COUNT, 5], [MaxCountType.VIDEO_MAX_COUNT, 5]]); this.pickerController.setMaxSelected(maxSelect); })
- 用法4:设置PhotoPickerComponent组件大图页显示的图片。uri可通过OnItemClicked回调获取。
Image(uri).height('10%').width('20%').backgroundColor(this.allBackGroundColor).onClick(() => {
console.log('uri = ' + uri);
this.pickerController.setPhotoBrowserItem(uri, PhotoBrowserRange.ALL);
})