鸿蒙 图片和视频选择组件PhotoPicker
摘要:HarmonyOS的PhotoPicker组件实现了安全便捷的多媒体文件访问,支持图片和视频选择而无需申请存储权限。该组件提供双视图模式(宫格/大图)、搜索功能和相机入口集成,开发者可通过PickerOptions配置选择参数,利用PickerController控制组件行为。开发步骤包括导入模块、创建实例、配置参数、实现8个关键回调函数和构建UI界面。注意事项包括URI只读性质、文件属性获
本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
一、PhotoPicker组件
PhotoPicker组件是HarmonyOS中用于访问用户图片和视频资源的系统组件。可以将该组件嵌入应用界面,用户选择图片或视频后,组件直接返回资源URI,无需应用申请读取存储权限,实现了安全便捷的多媒体文件访问。
二、特性
-
零权限访问:用户授权选择后直接获取资源URI,无需申请相册读写权限
-
多媒体支持:同时支持图片和视频文件的选择
-
双视图模式:
-
宫格视图:显示缩略图列表
-
大图视图:全屏预览选中的图片/视频
-
-
功能多:
-
内置搜索功能
-
相机入口集成
-
多选控制(设置最大选择数量)
-
自定义UI样式
-
三、开发步骤
步骤1:导入必要模块
import {
PhotoPickerComponent, // 主组件
PickerController, // 组件控制器
PickerOptions, // 配置选项
DataType, // 数据类型
BaseItemInfo, // 基础项目信息
ItemInfo, // 项目信息
PhotoBrowserInfo, // 大图浏览器信息
ItemType, // 项目类型枚举
ClickType, // 点击类型枚举
MaxCountType, // 最大数量类型
PhotoBrowserRange, // 大图浏览范围
ReminderMode, // 提醒模式
photoAccessHelper // 照片访问助手
} from '@kit.MediaLibraryKit';
步骤2:创建组件实例和状态变量
@Entry
@Component
struct PhotoPickerComponentDemo {
// 配置选项实例
pickerOptions: PickerOptions = new PickerOptions();
// 组件控制器实例
@State pickerController: PickerController = new PickerController();
// 已选择的图片URI列表
@State selectUris: Array<string> = new Array<string>();
// 当前查看的图片URI
@State currentUri: string = '';
// 是否显示大图模式
@State isBrowserShow: boolean = false;
}
步骤3:初始化配置参数
在组件生命周期中配置PickerOptions:
aboutToAppear() {
// 设置可选择的文件类型(图片和视频)
this.pickerOptions.MIMEType =
photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE;
// 最大选择数量为5
this.pickerOptions.maxSelectNumber = 5;
// 超出最大选择数量时使用Toast提醒
this.pickerOptions.maxSelectedReminderMode = ReminderMode.TOAST;
// 显示搜索框
this.pickerOptions.isSearchSupported = true;
// 显示相机入口
this.pickerOptions.isPhotoTakingSupported = true;
}
步骤4:回调函数(主要有8个)
1. onItemClicked - 项目点击回调
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) {
// 点击相机项目
return true; // true: 拉起系统相机; false: 应用自行处理
} else {
if (clickType === ClickType.SELECTED) {
// 项目被选中
if (uri) {
this.selectUris.push(uri);
this.pickerOptions.preselectedUris = [...this.selectUris];
}
return true; // true: 显示勾选状态
} else {
// 项目被取消选中
if (uri) {
this.selectUris = this.selectUris.filter((item: string) => item != uri);
this.pickerOptions.preselectedUris = [...this.selectUris];
}
}
return true;
}
}
2. onEnterPhotoBrowser - 进入大图模式回调
private onEnterPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean {
this.isBrowserShow = true;
return true;
}
3. onExitPhotoBrowser - 退出大图模式回调
private onExitPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean {
this.isBrowserShow = false;
return true;
}
4. onPickerControllerReady - 控制器就绪回调
private onPickerControllerReady(): void {
// 可在此处通过控制器定制组件行为
// 例如:隐藏大图页的返回按钮
let elements: number[] = [PhotoBrowserUIElement.BACK_BUTTON];
this.pickerController.setPhotoBrowserUIElementVisibility(elements, false);
}
5. onPhotoBrowserChanged - 大图滑动切换回调
private onPhotoBrowserChanged(browserItemInfo: BaseItemInfo): boolean {
this.currentUri = browserItemInfo.uri ?? '';
return true;
}
6. onSelectedItemsDeleted - 已选项目被删除回调
private onSelectedItemsDeleted(baseItemInfos: Array<BaseItemInfo>): void {
// 处理已选项目被用户删除的情况
}
7. onExceedMaxSelected - 超出最大选择数量回调
private onExceedMaxSelected(exceedMaxCountType: MaxCountType): void {
// 处理用户尝试选择超过最大数量限制的情况
}
8. onCurrentAlbumDeleted - 当前相册被删除回调
private onCurrentAlbumDeleted(): void {
// 处理当前浏览的相册被删除的情况
}
步骤5:构建UI界面
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) {
// 1. PhotoPicker主组件
PhotoPickerComponent({
pickerOptions: this.pickerOptions,
onItemClicked: (itemInfo: ItemInfo, clickType: ClickType): boolean =>
this.onItemClicked(itemInfo, clickType),
onEnterPhotoBrowser: (photoBrowserInfo: PhotoBrowserInfo): boolean =>
this.onEnterPhotoBrowser(photoBrowserInfo),
onExitPhotoBrowser: (photoBrowserInfo: PhotoBrowserInfo): boolean =>
this.onExitPhotoBrowser(photoBrowserInfo),
onPickerControllerReady: (): void =>
this.onPickerControllerReady(),
onPhotoBrowserChanged: (browserItemInfo: BaseItemInfo): boolean =>
this.onPhotoBrowserChanged(browserItemInfo),
onSelectedItemsDeleted: (baseItemInfos: Array<BaseItemInfo>) =>
this.onSelectedItemsDeleted(baseItemInfos),
onExceedMaxSelected: (exceedMaxCountType: MaxCountType) =>
this.onExceedMaxSelected(exceedMaxCountType),
onCurrentAlbumDeleted: () =>
this.onCurrentAlbumDeleted(),
pickerController: this.pickerController,
})
.width('100%')
.height('80%')
// 2. 底部控制栏(应用自定义)
if (this.isBrowserShow) {
// 大图模式下的底部缩略图栏
Row() {
ForEach(this.selectUris, (uri: string) => {
if (uri === this.currentUri) {
// 当前查看的图片:红色边框高亮
Image(uri)
.height(50)
.width(50)
.borderWidth(1)
.borderColor('red')
} else {
// 其他已选图片:可点击切换
Image(uri)
.height(50)
.width(50)
.onClick(() => {
// 更新选中列表并跳转到指定图片
this.pickerController.setData(
DataType.SET_SELECTED_URIS,
this.selectUris
);
this.pickerController.setPhotoBrowserItem(
uri,
PhotoBrowserRange.ALL
);
})
}
}, (uri: string) => JSON.stringify(uri))
}
.alignSelf(ItemAlign.Center)
.margin(this.selectUris.length ? 10 : 0)
} else {
// 宫格模式下的预览按钮
Button('预览已选项目')
.width('33%')
.alignSelf(ItemAlign.Start)
.height('5%')
.margin(10)
.onClick(() => {
if (this.selectUris.length > 0) {
// 跳转到大图模式,仅显示已选项目
this.pickerController.setPhotoBrowserItem(
this.selectUris[0],
PhotoBrowserRange.SELECTED_ONLY
);
}
})
}
}
.width('100%')
.height('100%')
}
四、控制器(PickerController)常用方法
1. 控制大图模式元素可见性
// 隐藏大图页的返回按钮
let elements: number[] = [PhotoBrowserUIElement.BACK_BUTTON];
this.pickerController.setPhotoBrowserUIElementVisibility(elements, false);
2. 跳转到指定图片
// 跳转到指定URI的图片
// PhotoBrowserRange.ALL: 显示所有项目
// PhotoBrowserRange.SELECTED_ONLY: 仅显示已选项目
this.pickerController.setPhotoBrowserItem(uri, PhotoBrowserRange.ALL);
3. 更新选中列表
// 设置组件内部的选中URI列表
this.pickerController.setData(DataType.SET_SELECTED_URIS, this.selectUris);
4. 刷新数据
// 重新加载图片/视频数据
this.pickerController.setData(DataType.REFRESH, null);
五、注意事项
1. URI的只读性质
-
回调函数返回的URI是只读URI,只能用于读取文件数据
-
不能直接在回调中使用这些URI打开文件
-
需要将URI保存到全局变量中,后续再使用
2. 文件属性获取
如果需要获取文件的元数据(大小、时间、路径等):
// 需要使用文件管理API
import fs from '@ohos.file.fs';
// 根据URI获取文件属性
3. 回调函数返回值
-
返回
true:执行系统默认行为 -
返回
false:阻止默认行为,由应用处理
4. 相机入口处理
当用户点击相机项目时:
-
返回
true:自动调用系统相机 -
返回
false:不调用系统相机,应用可自定义拍照逻辑
六、配置选项(PickerOptions)
主要配置项:
-
MIMEType:文件类型筛选
-
IMAGE_TYPE:仅图片 -
VIDEO_TYPE:仅视频 -
IMAGE_VIDEO_TYPE:图片和视频
-
-
maxSelectNumber:最大选择数量
-
maxSelectedReminderMode:超出限制提醒方式
-
ReminderMode.NONE:不提醒 -
ReminderMode.TOAST:Toast提示 -
ReminderMode.DIALOG:对话框提示
-
-
isSearchSupported:是否显示搜索框
-
isPhotoTakingSupported:是否显示相机入口
-
preselectedUris:预选中的URI列表
更多推荐



所有评论(0)