system_media_picker 1.0.1 copy "system_media_picker: ^1.0.1" to clipboard
system_media_picker: ^1.0.1 copied to clipboard

Permission-free image and video picker for Flutter. Wraps the Android System Photo Picker and iOS PHPickerViewController behind a single Dart API — no READ_MEDIA_* / NSPhotoLibrary* declarations needed.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'system_media_picker minimal example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: const _PickerPage(),
    );
  }
}

class _PickerPage extends StatefulWidget {
  const _PickerPage();

  @override
  State<_PickerPage> createState() => _PickerPageState();
}

class _PickerPageState extends State<_PickerPage> {
  // The opinionated controller is the easiest way to wire the plugin
  // to a UI: it owns the selection, enforces the limit, and tracks
  // loading / success / error state.
  late final MediaPickerController _controller;

  @override
  void initState() {
    super.initState();
    _controller = MediaPickerController(initialLimit: 5);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('system_media_picker')),
      body: AnimatedBuilder(
        animation: _controller,
        builder: (context, _) => Column(
          children: [
            if (_controller.isLoading) const LinearProgressIndicator(),
            if (_controller.errorMessage != null)
              Container(
                color: Theme.of(context).colorScheme.errorContainer,
                width: double.infinity,
                padding: const EdgeInsets.all(12),
                child: Text(
                  _controller.errorMessage!,
                  style: TextStyle(
                    color: Theme.of(context).colorScheme.onErrorContainer,
                  ),
                ),
              ),
            Padding(
              padding: const EdgeInsets.all(12),
              child: Text(
                'Selected ${_controller.items.length} of ${_controller.limit} '
                '(${_controller.imageCount} images, '
                '${_controller.videoCount} videos)',
              ),
            ),
            Expanded(
              child: GridView.builder(
                padding: const EdgeInsets.all(8),
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 3,
                  mainAxisSpacing: 8,
                  crossAxisSpacing: 8,
                ),
                itemCount: _controller.items.length,
                itemBuilder: (context, i) {
                  final item = _controller.items[i];
                  return GestureDetector(
                    onLongPress: () => _controller.removeAt(i),
                    child: ClipRRect(
                      borderRadius: BorderRadius.circular(8),
                      child: item.isImage
                          ? Image.file(item.file, fit: BoxFit.cover)
                          : Container(
                              color: Colors.black87,
                              alignment: Alignment.center,
                              child: const Icon(
                                Icons.play_circle_outline,
                                color: Colors.white,
                                size: 36,
                              ),
                            ),
                    ),
                  );
                },
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(12),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  ElevatedButton.icon(
                    onPressed:
                        _controller.isLoading || _controller.isAtCapacity
                        ? null
                        : _controller.pickImages,
                    icon: const Icon(Icons.image_outlined),
                    label: const Text('Pick images'),
                  ),
                  ElevatedButton.icon(
                    onPressed:
                        _controller.isLoading || _controller.isAtCapacity
                        ? null
                        : _controller.pickVideos,
                    icon: const Icon(Icons.video_library_outlined),
                    label: const Text('Pick videos'),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
0
likes
140
points
23
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Permission-free image and video picker for Flutter. Wraps the Android System Photo Picker and iOS PHPickerViewController behind a single Dart API — no READ_MEDIA_* / NSPhotoLibrary* declarations needed.

Repository (GitHub)
View/report issues

Topics

#picker #media #images #video #photos

License

MIT (license)

Dependencies

flutter

More

Packages that depend on system_media_picker

Packages that implement system_media_picker