Flutter媒体库管理插件media_gallery2的使用

Flutter媒体库管理插件media_gallery2的使用

pub package

一个用于Flutter的插件,可以列出原生图库项目。

安装

首先,在pubspec.yaml文件中添加media_gallery2作为依赖:

dependencies:
  media_gallery2: ^最新版本号

iOS

Info.plist文件中添加以下键值对:

<key>NSPhotoLibraryUsageDescription</key>
<string>Example usage description</string>

Android

AndroidManifest.xml文件中添加以下权限:

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

你还需要管理这些权限(例如通过permission_handler插件)。详情请参见示例

使用

列出媒体集合

final List<MediaCollection> collections = await MediaGallery.listMediaCollections(
    mediaTypes: [MediaType.image, MediaType.video],
);

在集合中列出媒体

final MediaPage imagePage = await collection.getMedias(
    mediaType: MediaType.image,
    take: 500,
);
final MediaPage videoPage = await collection.getMedias(
    mediaType: MediaType.video,
    take: 500,
);
final List<Media> allMedias = [
    ...imagePage.items,
    ...videoPage.items,
]
..sort((x, y) => y.creationDate.compareTo(x.creationDate));

加载更多媒体

if (!imagePage.isLast) {
    final nextImagePage = await imagePage.nextPage();
    // 处理加载更多媒体的逻辑
}

获取文件

final File file = await media.getFile();

获取缩略图数据

final List<int> data = await media.getThumbnail();

显示缩略图

MediaThumbnailProvider, MediaCollectionThumbnailProvider 可用于显示缩略图图像(这里使用了transparent_image):

FadeInImage(
    fit: BoxFit.cover,
    placeholder: MemoryImage(kTransparentImage),
    image: MediaThumbnailProvider(
        media: media,
    ),
)

显示媒体

你可以使用MediaImageProvider来显示图像(这里也使用了transparent_image):

FadeInImage(
    fit: BoxFit.cover,
    placeholder: MemoryImage(kTransparentImage),
    image: MediaImageProvider(
        media: media,
    ),
)

要显示视频,你可以使用video_player插件。

图片/视频选择器

picker

你可以轻松地构建一个图库选择器。

详情请参见示例

示例代码

import 'package:flutter/material.dart';
import 'package:media_gallery2/media_gallery2.dart';
import 'package:media_gallery2_example/picker/picker.dart';
import 'package:media_gallery2_example/picker/selection.dart';

import 'media.dart';
import 'picker/thumbnail.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  MediaPickerSelection selection;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text("Media Gallery"),
        ),
        body: SelectionGrid(
          selection: selection,
        ),
        floatingActionButton: Builder(
          builder: (context) => FloatingActionButton(
            onPressed: () async {
              final result = await MediaPicker.show(context);
              if (result != null) {
                setState(() => selection = result);
              }
            },
            child: Icon(Icons.image),
          ),
        ),
      ),
    );
  }
}

class SelectionGrid extends StatelessWidget {
  final MediaPickerSelection selection;

  const SelectionGrid({
    required this.selection,
  });

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.all(20.0),
      padding: EdgeInsets.all(20.0),
      decoration: BoxDecoration(
        color: Colors.black12,
        borderRadius: BorderRadius.circular(4.0),
      ),
      child: selection == null || selection.selectedMedias.isEmpty
          ? Text("No selection")
          : Wrap(
              spacing: 10.0,
              runSpacing: 10.0,
              children: [
                ...selection.selectedMedias.map(
                  (x) => GestureDetector(
                    onTap: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => MediaViewerPage(media: x),
                        ),
                      );
                    },
                    child: SizedBox(
                      width: 128,
                      height: 128,
                      child: MediaThumbnailImage(media: x),
                    ),
                  ),
                ),
              ],
            ),
    );
  }
}

更多关于Flutter媒体库管理插件media_gallery2的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter媒体库管理插件media_gallery2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


media_gallery2 是一个 Flutter 插件,用于访问和管理设备上的媒体库(照片、视频等)。它允许你从设备的相册中获取媒体文件,并在 Flutter 应用程序中显示它们。以下是如何使用 media_gallery2 插件的步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  media_gallery2: ^0.1.0 # 请检查最新版本

然后运行 flutter pub get 来安装依赖。

2. 请求权限

在访问设备的媒体库之前,你需要请求相应的权限。通常需要 READ_EXTERNAL_STORAGE 权限。你可以使用 permission_handler 插件来请求权限。

首先,添加 permission_handler 插件的依赖:

dependencies:
  permission_handler: ^10.0.0 # 请检查最新版本

然后,在代码中请求权限:

import 'package:permission_handler/permission_handler.dart';

Future<void> requestPermissions() async {
  if (await Permission.storage.request().isGranted) {
    // 权限已授予
  } else {
    // 权限被拒绝
  }
}

3. 初始化 MediaGallery

在获取权限后,你可以初始化 MediaGallery 并开始获取媒体文件。

import 'package:media_gallery2/media_gallery2.dart';

Future<void> initMediaGallery() async {
  await MediaGallery.initialize();
}

4. 获取相册列表

你可以使用 MediaGallery.listAlbums 方法来获取设备上的相册列表。

Future<List<Album>> getAlbums() async {
  return await MediaGallery.listAlbums();
}

5. 获取相册中的媒体文件

你可以使用 MediaGallery.listMedia 方法来获取特定相册中的媒体文件。

Future<List<Media>> getMedia(Album album) async {
  return await MediaGallery.listMedia(album: album);
}

6. 显示媒体文件

你可以使用 MediaPage 来显示媒体文件的内容。例如,显示图片:

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

class MediaPage extends StatelessWidget {
  final Media media;

  MediaPage({required this.media});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Media'),
      ),
      body: Center(
        child: FutureBuilder<MediaFile>(
          future: media.getFile(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.hasData) {
                return Image.file(snapshot.data!.file);
              } else {
                return Text('Failed to load media');
              }
            } else {
              return CircularProgressIndicator();
            }
          },
        ),
      ),
    );
  }
}

7. 完整示例

以下是一个完整的示例,展示了如何使用 media_gallery2 插件来获取并显示设备相册中的图片:

import 'package:flutter/material.dart';
import 'package:media_gallery2/media_gallery2.dart';
import 'package:permission_handler/permission_handler.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await requestPermissions();
  await MediaGallery.initialize();
  runApp(MyApp());
}

Future<void> requestPermissions() async {
  if (await Permission.storage.request().isGranted) {
    print('Permission granted');
  } else {
    print('Permission denied');
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Media Gallery Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MediaGalleryScreen(),
    );
  }
}

class MediaGalleryScreen extends StatefulWidget {
  @override
  _MediaGalleryScreenState createState() => _MediaGalleryScreenState();
}

class _MediaGalleryScreenState extends State<MediaGalleryScreen> {
  List<Album> albums = [];
  List<Media> media = [];

  @override
  void initState() {
    super.initState();
    _loadAlbums();
  }

  Future<void> _loadAlbums() async {
    albums = await MediaGallery.listAlbums();
    if (albums.isNotEmpty) {
      _loadMedia(albums.first);
    }
    setState(() {});
  }

  Future<void> _loadMedia(Album album) async {
    media = await MediaGallery.listMedia(album: album);
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Media Gallery'),
      ),
      body: Column(
        children: [
          DropdownButton<Album>(
            value: albums.isNotEmpty ? albums.first : null,
            onChanged: (Album? album) {
              if (album != null) {
                _loadMedia(album);
              }
            },
            items: albums.map<DropdownMenuItem<Album>>((Album album) {
              return DropdownMenuItem<Album>(
                value: album,
                child: Text(album.name),
              );
            }).toList(),
          ),
          Expanded(
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 3,
              ),
              itemCount: media.length,
              itemBuilder: (context, index) {
                return GestureDetector(
                  onTap: () {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => MediaPage(media: media[index]),
                      ),
                    );
                  },
                  child: FutureBuilder<MediaFile>(
                    future: media[index].getFile(),
                    builder: (context, snapshot) {
                      if (snapshot.connectionState == ConnectionState.done) {
                        if (snapshot.hasData) {
                          return Image.file(
                            snapshot.data!.file,
                            fit: BoxFit.cover,
                          );
                        } else {
                          return Center(child: Text('Failed to load media'));
                        }
                      } else {
                        return Center(child: CircularProgressIndicator());
                      }
                    },
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

class MediaPage extends StatelessWidget {
  final Media media;

  MediaPage({required this.media});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Media'),
      ),
      body: Center(
        child: FutureBuilder<MediaFile>(
          future: media.getFile(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.hasData) {
                return Image.file(snapshot.data!.file);
              } else {
                return Text('Failed to load media');
              }
            } else {
              return CircularProgressIndicator();
            }
          },
        ),
      ),
    );
  }
}

8. 注意事项

  • 确保在 AndroidManifest.xml 文件中添加了必要的权限:
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
  • 在 iOS 上,你需要在 Info.plist 文件中添加相应的权限描述:
    <key>NSPhotoLibraryUsageDescription</key>
    <string>We need access to your photo library to display your photos.</string>
回到顶部