Flutter图片选择器插件as_instapicker的使用

Flutter图片选择器插件as_instapicker的使用

📚 安装

首先,在你的pubspec.yaml文件中添加该插件:

dependencies:
  insta_assets_picker: ^3.0.0-dev.1

‼️ 不要跳过此部分

由于该插件是flutter_wechat_assets_picker的一个自定义委托,你必须遵循该插件的安装指南。请确保你已经阅读并遵循了相关指南。

👀 使用

以下是一个简单的示例,展示了如何调用图片选择器插件:

import 'package:flutter/material.dart';
import 'package:insta_assets_picker/insta_assets_picker.dart';

Future<List<AssetEntity>?> callPicker(BuildContext context) async {
  final pickerResult = await InstaAssetPicker.pickAssets(
    context,
    pickerConfig: InstaAssetPickerConfig(
      title: '选择资产',
    ),
    maxAssets: 10,
    onCompleted: (Stream<InstaAssetsExportDetails> stream) {
      // 处理裁剪流结果
      // 可以使用StreamBuilder来处理数据
      // - 在同一页面(closeOnComplete=true)
      // - 发送到另一个页面(closeOnComplete=false)
      // 或者使用`stream.listen`手动处理数据
      // - ...
    },
  );
  return pickerResult;
}

Picker配置

你可以通过pickerConfig来配置选择器的各种属性。具体可以参考flutter_wechat_assets_picker的文档。

本地化

你可以通过pickerConfig中的locale字段来设置本地化语言。具体可以参考flutter_wechat_assets_picker的文档。

主题定制

你可以通过pickerConfig中的pickerTheme字段来自定义主题。以下是一个示例:

final theme = InstaAssetPicker.themeData(Theme.of(context).primaryColor);
InstaAssetPicker.pickAssets(
  context,
  pickerConfig: InstaAssetPickerConfig(
    pickerTheme: theme.copyWith(
      canvasColor: Colors.black, // 背景颜色
      splashColor: Colors.grey, // 点击时的溅起效果颜色
      colorScheme: theme.colorScheme.copyWith(
        background: Colors.black87, // 相册列表背景颜色
      ),
      appBarTheme: theme.appBarTheme.copyWith(
        backgroundColor: Colors.black, // 应用栏背景颜色
        titleTextStyle: Theme.of(context)
            .appBarTheme
            .titleTextStyle
            ?.copyWith(color: Colors.white), // 改变应用栏标题文本样式
      ),
      // 自定义确认按钮样式
      textButtonTheme: TextButtonThemeData(
        style: TextButton.styleFrom(
          foregroundColor: Colors.blue,
          disabledForegroundColor: Colors.red,
        ),
      ),
    ),
  ),
  onCompleted: (_) {},
);

裁剪定制

你可以通过pickerConfig中的cropDelegate字段来设置裁剪比例。以下是一个示例:

InstaAssetPicker.pickAssets(
  context,
  pickerConfig: InstaAssetPickerConfig(
    cropDelegate: InstaAssetCropDelegate(
      // 设置裁剪时使用的首选大小
      preferredSize: 1080,
      cropRatios: [
        // 允许设置可选的裁剪比例列表
        // 默认值为[1/1, 4/5],类似于Instagram
        // 如果只设置一个参数,则裁剪按钮将不会显示(#10)
        // 如果裁剪比例与默认值不同,则裁剪按钮将显示选定的比例值(例如:1:1)而不是展开箭头
      ],
    ),
  ),
  onCompleted: (_) {},
);

摄像头

从版本2.0.0开始,你可以通过specialItemBuilder和/或actionsBuilder触发拍照操作。请注意,拍照功能必须由你自己实现,但选择器现在能够刷新列表并选择新拍摄的照片。

视频

从版本3.0.0开始,支持视频选择。你可以选择视频资产并在选择器中直接选择裁剪区域。但是,视频处理是一个复杂的操作,因此需要你自己处理。如果你想要预览视频结果,可以使用InstaAssetCropTransform来调整Image或VideoPlayer以适应选定的裁剪区域。

示例代码

以下是完整的示例代码,展示了如何在应用中集成图片选择器插件:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'pages/stateless_pickers.dart';
import 'pages/camera/camera_picker.dart';
import 'pages/camera/wechat_camera_picker.dart';
import 'pages/restorable_picker.dart';
import 'post_provider.dart';
import 'widgets/insta_picker_interface.dart';
import 'widgets/post.dart';
import 'package:provider/provider.dart';

const kDefaultColor = Colors.deepPurple;

void main() => runApp(
      ChangeNotifierProvider(
        create: (context) => PostProvider(),
        child: const MyApp(),
      ),
    );

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Insta Assets Picker Demo',
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(
          seedColor: kDefaultColor,
          brightness: Brightness.dark,
        ),
        cardTheme: const CardTheme(
          elevation: 2,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(Radius.circular(8)),
          ),
        ),
        listTileTheme: const ListTileThemeData(
          enableFeedback: true,
          contentPadding: EdgeInsets.all(16),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(Radius.circular(8)),
          ),
          titleTextStyle: TextStyle(fontWeight: FontWeight.w600),
          leadingAndTrailingTextStyle: TextStyle(fontSize: 24),
        ),
      ),
      home: const PickersScreen(),
      localizationsDelegates: const [
        GlobalWidgetsLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const [Locale('zh')],
    );
  }
}

class PickersScreen extends StatelessWidget {
  const PickersScreen({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    final List<InstaPickerInterface> pickers = [
      const SinglePicker(),
      const MultiplePicker(),
      const RestorablePicker(),
      const CameraPicker(),
      const WeChatCameraPicker(),
    ];

    return Scaffold(
      appBar: AppBar(
        title: const Text('Insta pickers'),
        actions: [
          IconButton(
            onPressed: () => Navigator.of(context).push(
              MaterialPageRoute(builder: (context) => const PostsPage()),
            ),
            icon: const Icon(Icons.feed, semanticLabel: 'Feed'),
          )
        ],
      ),
      body: ListView.separated(
        padding: const EdgeInsets.all(16),
        itemBuilder: (BuildContext context, int index) {
          final PickerDescription description = pickers[index].description;

          return Card(
            child: ListTile(
              leading: Text(description.icon),
              title: Text(description.label),
              subtitle: description.description != null
                  ? Text(description.description!)
                  : null,
              trailing: const Icon(Icons.chevron_right_rounded),
              onTap: () => Navigator.of(context).push(
                MaterialPageRoute(builder: (context) => pickers[index]),
              ),
            ),
          );
        },
        separatorBuilder: (_, __) => const SizedBox(height: 4),
        itemCount: pickers.length,
      ),
    );
  }
}

更多关于Flutter图片选择器插件as_instapicker的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图片选择器插件as_instapicker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


as_instapicker 是一个 Flutter 插件,用于从设备中选择图片,类似于 Instagram 的图片选择器。它提供了简洁的 UI 和丰富的功能,允许用户从相册中选择单张或多张图片。

安装插件

首先,你需要在 pubspec.yaml 文件中添加 as_instapicker 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  as_instapicker: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来安装插件。

使用插件

1. 导入插件

在你的 Dart 文件中导入 as_instapicker 插件:

import 'package:as_instapicker/as_instapicker.dart';

2. 打开图片选择器

你可以使用 InstaPicker.pickImages 方法来打开图片选择器。这个方法返回一个 List<InstaImage>,其中 InstaImage 包含了所选图片的信息。

void openImagePicker() async {
  try {
    List<InstaImage> images = await InstaPicker.pickImages(
      maxImages: 5, // 最大选择图片数量
      enableCamera: true, // 是否启用相机
      enableVideo: false, // 是否允许选择视频
    );

    // 处理选择的图片
    for (var image in images) {
      print('Selected image path: ${image.path}');
      // 你可以使用 image.path 来显示或上传图片
    }
  } catch (e) {
    print('Error: $e');
  }
}

3. 显示图片

你可以使用 Image.file 来显示用户选择的图片:

import 'package:flutter/material.dart';
import 'dart:io';

class ImagePickerScreen extends StatefulWidget {
  @override
  _ImagePickerScreenState createState() => _ImagePickerScreenState();
}

class _ImagePickerScreenState extends State<ImagePickerScreen> {
  List<File> _images = [];

  void _openImagePicker() async {
    try {
      List<InstaImage> images = await InstaPicker.pickImages(
        maxImages: 5,
        enableCamera: true,
        enableVideo: false,
      );

      setState(() {
        _images = images.map((image) => File(image.path)).toList();
      });
    } catch (e) {
      print('Error: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Picker'),
      ),
      body: Column(
        children: [
          Expanded(
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 3,
                crossAxisSpacing: 4.0,
                mainAxisSpacing: 4.0,
              ),
              itemCount: _images.length,
              itemBuilder: (context, index) {
                return Image.file(
                  _images[index],
                  fit: BoxFit.cover,
                );
              },
            ),
          ),
          ElevatedButton(
            onPressed: _openImagePicker,
            child: Text('Pick Images'),
          ),
        ],
      ),
    );
  }
}

其他功能

  • 多选支持:你可以通过 maxImages 参数来控制用户最多可以选择多少张图片。
  • 相机支持:通过 enableCamera 参数,用户可以直接拍照并选择照片。
  • 视频支持:通过 enableVideo 参数,用户可以选择视频文件。

注意事项

  • 在 Android 上,你可能需要在 AndroidManifest.xml 中添加相机和存储权限。
  • 在 iOS 上,你可能需要在 Info.plist 中添加相册和相机权限的描述。

权限配置

Android

AndroidManifest.xml 中添加以下权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

iOS

Info.plist 中添加以下描述:

<key>NSCameraUsageDescription</key>
<string>We need access to your camera to take pictures.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library to select pictures.</string>
回到顶部