1

I have been trying to recreate this (at the bottom of the page) but with flutter version 2.12.0 and the package photo_manager. I have tried to automatically do this, but unfortunately, I am not able to resolve the following part to the newer dart syntax.

builder: (BuildContext context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done)
                return Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Image.memory(
                        snapshot.data, //wrong data type here
                        fit: BoxFit.cover,
                      ),
                    ),

In the orignal written code (for 2.7) it worked perfectly fine.

Paul
  • 1,349
  • 1
  • 14
  • 26

1 Answers1

8

Simply call GridGallery() as a normal widget. Make sure to set up permissions to access the device gallery before. Have a look at the build Widget to configure the grid.

import 'dart:typed_data';

import 'package:flutter/material.dart';

import 'package:photo_manager/photo_manager.dart';

class GridGallery extends StatefulWidget {
  final ScrollController? scrollCtr;

  const GridGallery({
    Key? key,
    this.scrollCtr,
  }) : super(key: key);

  @override
  _GridGalleryState createState() => _GridGalleryState();
}

class _GridGalleryState extends State<GridGallery> {
  List<Widget> _mediaList = [];
  int currentPage = 0;
  int? lastPage;

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

  _handleScrollEvent(ScrollNotification scroll) {
    if (scroll.metrics.pixels / scroll.metrics.maxScrollExtent > 0.33) {
      if (currentPage != lastPage) {
        _fetchNewMedia();
      }
    }
  }

  _fetchNewMedia() async {
    lastPage = currentPage;
    final PermissionState _ps = await PhotoManager.requestPermissionExtend();
    if (_ps.isAuth) {
      // success
//load the album list
      List<AssetPathEntity> albums =
          await PhotoManager.getAssetPathList(
      onlyAll: true);
      print(albums);
      List<AssetEntity> media =
          await albums[0].getAssetListPaged(size: 60, page: currentPage); //preloading files
      print(media);
      List<Widget> temp = [];
      for (var asset in media) {
        temp.add(
          FutureBuilder(
            future: asset.thumbnailDataWithSize(ThumbnailSize(200, 200)), //resolution of thumbnail
            builder:
                (BuildContext context, AsyncSnapshot<Uint8List?> snapshot) {
              if (snapshot.connectionState == ConnectionState.done)
                return Container(
                  child: Stack(
                    children: <Widget>[
                      Positioned.fill(
                        child: Image.memory(
                          snapshot.data!,
                          fit: BoxFit.cover,
                        ),
                      ),
                      if (asset.type == AssetType.video)
                        Align(
                          alignment: Alignment.bottomRight,
                          child: Padding(
                            padding: EdgeInsets.only(right: 5, bottom: 5),
                            child: Icon(
                              Icons.videocam,
                              color: Colors.white,
                            ),
                          ),
                        ),
                    ],
                  ),
                );
              return Container();
            },
          ),
        );
      }
      setState(() {
        _mediaList.addAll(temp);
        currentPage++;
      });
    } else {
      // fail
      /// if result is fail, you can call `PhotoManager.openSetting();`  to open android/ios applicaton's setting to get permission
    }
  }

  @override
  Widget build(BuildContext context) {
    return NotificationListener<ScrollNotification>(
      onNotification: (ScrollNotification scroll) {
        _handleScrollEvent(scroll);
        return false;
      },
      child: GridView.builder(
          controller: widget.scrollCtr,
          itemCount: _mediaList.length,
          gridDelegate:
              SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
          itemBuilder: (BuildContext context, int index) {
            return _mediaList[index];
          }),
    );
  }
}
Paul
  • 1,349
  • 1
  • 14
  • 26
  • thanks for share this code, how to get path of image for upload to server? – ff .n Jan 09 '22 at 09:17
  • Pass `snapshot.data!` from the build and save it additionally (or return it when pressed). This data is the local file `Uint8List` type. Have a look [here](https://stackoverflow.com/questions/58793993/how-to-convert-uint8list-image-to-file-image-for-upload-in-flutter-web) at how to get the local file, after that you can also upload that with your API. Does that help? – Paul Jan 09 '22 at 23:00
  • yes, thank you very much – ff .n Jan 16 '22 at 06:43
  • i have another question, this library show image with low quality....Do you have a solution? – ff .n Jan 16 '22 at 13:00
  • @ff.n The low quality is on purpose to reduce memory. There is a line `future: asset.thumbDataWithSize(200, 200),` which reduces the size. Change it if wanted. – Paul Jan 16 '22 at 16:03