Flutter资源文件选择插件fl_assets_picker的使用
Flutter资源文件选择插件fl_assets_picker的使用
fl_assets_picker
是一个简单的封装,用于方便地选择图片和视频资源。它集成了 wechat_assets_picker
和 wechat_camera_picker
,提供了多种选择资源的方式。
初始化配置
在使用 fl_assets_picker
之前,需要进行一些初始化配置:
void flAssetsPickerInit() {
FlAssetsPicker.assetBuilder = (entity, bool isThumbnail) =>
AssetBuilder(entity, isThumbnail: isThumbnail);
FlAssetsPicker.checkPermission = (PickerOptionalActions action) async {
if (!isMobile) return true;
if (action == PickerOptionalActions.gallery) {
if (isIOS) {
return (await Permission.photos.request()).isGranted;
} else if (isAndroid) {
final androidInfo = await DeviceInfoPlugin().androidInfo;
if (androidInfo.version.sdkInt < 33) {
return (await Permission.storage.request()).isGranted;
}
return (await Permission.photos.request()).isGranted &&
(await Permission.videos.request()).isGranted;
}
return false;
} else if (action == PickerOptionalActions.camera) {
final permissionState = await Permission.camera.request();
return permissionState.isGranted;
}
return false;
};
FlAssetsPicker.previewModalPopup = (_, Widget widget) => widget.popupDialog();
FlAssetsPicker.previewBuilder = (context, entity, allEntity) {
return FlPreviewGesturePageView(
pageView: ExtendedImageGesturePageView.builder(
itemCount: allEntity.length,
controller: ExtendedPageController(initialPage: allEntity.indexOf(entity)),
itemBuilder: (_, int index) => FlAssetsPicker.assetBuilder(allEntity[index], false)
)
);
};
FlAssetsPicker.errorCallback = (ErrorDes des) {
switch (des) {
case ErrorDes.maxBytes:
showToast('资源过大');
break;
case ErrorDes.maxCount:
showToast('超过最大数量');
break;
case ErrorDes.maxVideoCount:
showToast('超过最大视频数量');
break;
case ErrorDes.none:
showToast('未获取到资源');
break;
}
};
}
使用示例
单选
SingleAssetPicker();
多选
MultipleAssetPicker();
直接调用方法选择
void fun() {
/// 选择Actions
FlAssetsPicker.showPickActions();
/// 最原始的资源选择器
FlAssetsPicker.showPickAssets();
FlAssetsPicker.showPickAssetsWithDelegate();
/// 从相机拍摄
FlAssetsPicker.showPickFromCamera();
/// 依次选择Actions和资源选择器
FlAssetsPicker.showPickWithOptionalActions();
}
主应用
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
flAssetsPickerInit();
runApp(MaterialApp(
navigatorKey: FlExtended().navigatorKey,
debugShowCheckedModeBanner: false,
theme: ThemeData.light(useMaterial3: true),
darkTheme: ThemeData.dark(useMaterial3: true),
home: Scaffold(
appBar: AppBar(title: const Text('Fl Assets Picker')),
body: const _HomePage())));
}
class _HomePage extends StatelessWidget {
const _HomePage();
[@override](/user/override)
Widget build(BuildContext context) {
return Universal(
padding: const EdgeInsets.all(12),
isScroll: true,
children: [
const Text('单资源选择 混选').marginAll(12),
buildSingleAssetPicker(RequestType.common),
const Text('单资源选择 仅图片').marginAll(12),
buildSingleAssetPicker(RequestType.image),
const Text('单资源选择 仅视频').marginAll(12),
buildSingleAssetPicker(RequestType.video),
const Text('多资源选择 混选').marginAll(12),
buildMultipleAssetPicker(RequestType.common),
const Text('多资源选择 仅图片').marginAll(12),
buildMultipleAssetPicker(RequestType.image),
const Text('多资源选择 仅视频').marginAll(12),
buildMultipleAssetPicker(RequestType.video),
]);
}
Widget buildSingleAssetPicker(RequestType requestType) {
final actions = [
PickerActions(
action: PickerOptionalActions.gallery,
requestType: requestType,
text: const Text('图库选择')),
PickerActions(
action: PickerOptionalActions.camera,
requestType: requestType,
text: const Text('相机拍摄')),
const PickerActions(
action: PickerOptionalActions.cancel, text: Text('取消'))
];
return Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
SingleAssetPicker(
actions: actions,
renovate: (AssetEntity entity) async {
final file = await entity.file;
if (file != null) return await compressImage(file);
return null;
},
initialData: SingleAssetPicker.convertUrl(url),
itemConfig: AssetsPickerItemConfig(
borderRadius: BorderRadius.circular(10),
color: Colors.amberAccent),
onChanged: (ExtendedAssetEntity value) {
'onChanged ${value.realValueStr} realValue Type: ${value.realValue.runtimeType}'
.log();
}),
SingleAssetPicker(
actions: actions,
initialData: SingleAssetPicker.convertUrl(url),
itemConfig: AssetsPickerItemConfig(
borderRadius: BorderRadius.circular(40),
color: Colors.amberAccent),
onChanged: (ExtendedAssetEntity value) {
'onChanged ${value.realValueStr} realValue Type: ${value.realValue.runtimeType}'
.log();
}),
]);
}
Widget buildMultipleAssetPicker(RequestType requestType) => MultipleAssetPicker(
initialData: MultipleAssetPicker.convertUrls(url),
maxVideoCount: 6,
actions: [
PickerActions(
action: PickerOptionalActions.gallery,
text: const Text('图库选择'),
requestType: requestType),
PickerActions(
action: PickerOptionalActions.camera,
text: const Text('相机拍摄'),
requestType: requestType),
const PickerActions(
action: PickerOptionalActions.cancel, text: Text('取消')),
],
itemConfig: AssetsPickerItemConfig(
delete: const DefaultDeleteIcon(backgroundColor: Colors.blue),
deletionConfirmation: (_) async {
final value = await CupertinoAlertDialog(
content: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
constraints: const BoxConstraints(maxHeight: 100),
child: const Text('确定要删除么')),
actions: [
Universal(
height: 45,
alignment: Alignment.center,
onTap: () {
pop(false);
},
child: const BText('取消',
fontSize: 14, color: Colors.grey)),
Universal(
height: 45,
alignment: Alignment.center,
onTap: () {
pop(true);
},
child: const BText('确定',
fontSize: 14, color: Colors.grey)),
]).popupCupertinoModal< bool? >();
return value ?? false;
}),
onChanged: (List<ExtendedAssetEntity> value) {
'onChanged ${value.builder((item) => item.realValueStr)}'.log();
});
}
/// 图片压缩
Future<Uint8List?> compressImage(File file) async {
final fileName = file.path.removePrefix(file.parent.path);
final suffix = fileName.split('.').last.toLowerCase();
CompressFormat? format;
if (suffix == 'jpg' || suffix == 'jpeg') {
format = CompressFormat.jpeg;
} else if (suffix == 'png') {
format = CompressFormat.png;
} else if (suffix == 'webp') {
format = CompressFormat.webp;
} else if (suffix == 'heic') {
format = CompressFormat.heic;
}
if (format != null) {
return await FlutterImageCompress.compressWithFile(file.path,
format: format, minWidth: 480, minHeight: 480, quality: 80);
}
return null;
}
更多关于Flutter资源文件选择插件fl_assets_picker的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter资源文件选择插件fl_assets_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用fl_assets_picker
插件的示例代码。fl_assets_picker
是一个用于选择资源文件(如图片和视频)的插件。
步骤 1: 添加依赖
首先,你需要在pubspec.yaml
文件中添加fl_assets_picker
依赖:
dependencies:
flutter:
sdk: flutter
fl_assets_picker: ^latest_version # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
步骤 2: 导入插件
在你需要使用fl_assets_picker
的Dart文件中,导入插件:
import 'package:fl_assets_picker/fl_assets_picker.dart';
步骤 3: 使用插件
以下是一个简单的示例,展示了如何使用fl_assets_picker
来选择图片和视频:
import 'package:flutter/material.dart';
import 'package:fl_assets_picker/fl_assets_picker.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<AssetEntity> selectedAssets = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Asset Picker Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () async {
// 打开资源选择器
List<AssetEntity> result = await AssetsPicker.pickAssets(
context,
requestType: RequestType.imageAndVideo, // 可以选择图片和视频
maxAssetsCount: 9, // 最大选择数量
maxVideoDuration: 60, // 最大视频时长(秒)
gridCount: 3, // 每行显示多少个资源
pickerConfig: PickerConfig(
// 配置资源选择器的其他选项
showVideoPreview: true,
),
);
// 更新选择结果
setState(() {
selectedAssets = result;
});
},
child: Text('选择资源'),
),
if (selectedAssets.isNotEmpty) {
SizedBox(height: 20),
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 4,
mainAxisSpacing: 4,
),
itemCount: selectedAssets.length,
itemBuilder: (context, index) {
AssetEntity asset = selectedAssets[index];
return AssetThumb(
asset: asset,
width: 100,
height: 100,
);
},
),
}
],
),
),
);
}
}
注意事项
-
权限配置:
- 在Android中,你需要在
AndroidManifest.xml
中请求读写存储权限。 - 在iOS中,你需要在
Info.plist
中添加相应的权限描述。
- 在Android中,你需要在
-
错误处理:
- 在实际应用中,建议添加错误处理逻辑,以处理可能的异常情况,如用户拒绝权限请求等。
-
UI优化:
- 根据你的需求,可以自定义
AssetThumb
或其他UI组件的样式。
- 根据你的需求,可以自定义
希望这个示例能帮助你顺利地在Flutter项目中使用fl_assets_picker
插件。