Flutter资源文件选择插件fl_assets_picker的使用

Flutter资源文件选择插件fl_assets_picker的使用

fl_assets_picker 是一个简单的封装,用于方便地选择图片和视频资源。它集成了 wechat_assets_pickerwechat_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,
                  );
                },
              ),
            }
          ],
        ),
      ),
    );
  }
}

注意事项

  1. 权限配置

    • 在Android中,你需要在AndroidManifest.xml中请求读写存储权限。
    • 在iOS中,你需要在Info.plist中添加相应的权限描述。
  2. 错误处理

    • 在实际应用中,建议添加错误处理逻辑,以处理可能的异常情况,如用户拒绝权限请求等。
  3. UI优化

    • 根据你的需求,可以自定义AssetThumb或其他UI组件的样式。

希望这个示例能帮助你顺利地在Flutter项目中使用fl_assets_picker插件。

回到顶部