如何判断通过ImagePicker获取的XFile是图片还是视频?
解决方案
这里提供三种可行性高的实现方式,你可以根据自己的业务场景选择:
方案1:新增状态字段标记媒体类型(最推荐)
由于你拍照和录视频是完全独立的两个触发入口,直接新增字段标记类型是最稳妥、性能最高的方案,不会出现类型判断偏差的问题。
- 首先定义媒体类型枚举
enum MediaType { image, video }
- 在当前State类中新增存储类型的字段
XFile? file; Uint8List? bytes; MediaType? mediaType; // 新增字段存储媒体类型
- 修改两个拍摄方法,存储对应类型
handleTakePhoto() async { Navigator.pop(context); XFile? file = await ImagePicker() .pickImage(source: ImageSource.camera, maxWidth: 960, maxHeight: 675); // 增加空判断,避免用户取消拍摄时空异常 if (file == null) return; setState(() { this.file = file; bytes = File(file.path).readAsBytesSync(); mediaType = MediaType.image; // 标记为图片类型 }); } handleTakeVideo() async { Navigator.pop(context); XFile? file = await ImagePicker() .pickVideo(source: ImageSource.camera, maxDuration: const Duration(seconds: 10)); if (file == null) return; setState(() { this.file = file; bytes = File(file.path).readAsBytesSync(); mediaType = MediaType.video; // 标记为视频类型 }); }
- 后续使用时直接判断类型即可
if (mediaType == MediaType.image) { // 执行图片相关逻辑 } else if (mediaType == MediaType.video) { // 执行视频相关逻辑 }
方案2:通过XFile自带属性判断类型
如果你不想新增状态字段,可以直接通过XFile的mimeType或者文件后缀名判断类型,适合无法确定媒体获取入口的场景(比如从相册选文件)。
// 通过mimeType判断 bool get isImage => (file?.mimeType ?? '').startsWith('image/'); bool get isVideo => (file?.mimeType ?? '').startsWith('video/'); // 若部分设备mimeType获取异常,可以通过文件后缀判断 bool get isImageByExt { final ext = (file?.path ?? '').split('.').last.toLowerCase(); return ['jpg', 'jpeg', 'png', 'heic', 'webp'].contains(ext); }
方案3:抽离公共逻辑简化代码
你当前两段拍摄逻辑重复度很高,可以抽成公共方法,同时完成类型标记,减少冗余代码:
// 抽离的公共媒体选择方法 Future<void> pickMedia(MediaType type) async { Navigator.pop(context); XFile? file; if (type == MediaType.image) { file = await ImagePicker().pickImage( source: ImageSource.camera, maxWidth: 960, maxHeight: 675, ); } else if (type == MediaType.video) { file = await ImagePicker().pickVideo( source: ImageSource.camera, maxDuration: const Duration(seconds: 10), ); } if (file == null) return; setState(() { this.file = file; bytes = File(file.path).readAsBytesSync(); mediaType = type; }); } // 原有的两个触发方法可以简化为 handleTakePhoto() => pickMedia(MediaType.image); handleTakeVideo() => pickMedia(MediaType.video);
内容的提问来源于stack exchange,提问作者Lorenzo Cutrupi
相关产品推荐
相关产品推荐

