fluttercandies / flutter_photo_manager

A Flutter plugin that provides images, videos, and audio abstraction management APIs without interface integration, available on Android, iOS, macOS and OpenHarmony.
https://pub.dev/packages/photo_manager
Apache License 2.0
681 stars 309 forks source link

[How to use] Ho to correctly load and show images using AssetEntity.fromId ? #1210

Open vlavorini opened 8 hours ago

vlavorini commented 8 hours ago

Platforms

dart, Android, iOS, macOS

Description

What is the correct way to display images starting from the ID?

As example, with the following code I get the error:

The argument type 'Future<AssetEntity?>' can't be assigned to the parameter type 'AssetEntity'. dart[argument_type_not_assignable](https://dart.dev/diagnostics/argument_type_not_assignable)

And if I write await AssetEntity.fromId(retrEnt.localId) I get as error:

The await expression can only be used in an async function.

Can you help me?

P.S. I already filed a SO question

My code

class AnalyzeMedia extends StatefulWidget {
  @override
  AnalyzeMediaState createState() {
    return AnalyzeMediaState();
  }
}

class AnalyzeMediaState extends State<AnalyzeMedia> {
  final _formKey2 = GlobalKey<FormState>();
  late Future<List<RetrievedMedia>> futureClusterSamples;

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey2,
      child: Column(
        children: [
          ElevatedButton(
            /// doing something
          ),
          FutureBuilder<List<RetrievedMedia>>(
            future: futureClusterSamples,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                  return Column(
                    children: [
                      for (var retrEnt in snapshot.data!)
                        Image(
                          image: AssetEntityImageProvider(
                            await AssetEntity.fromId(retrEnt.localId),  // <--- HERE is the issue
                            isOriginal: false,
                            thumbnailSize: const ThumbnailSize.square(200),
                            thumbnailFormat: ThumbnailFormat.jpeg,
                          ),
                        )

                    ],
                  );
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }

              // By default, show a loading spinner.
              return const CircularProgressIndicator();
            },
          ),

        ],
      ),
    );
  }
}

Try do it

No response

vlavorini commented 7 hours ago

I can reply to my own question. Not sure this is the best way to do it, but using another FutureBuilder solves.

The pictures are succesfully shown by changing the part:

for (var retrEnt in snapshot.data!)
  Image(
    image: AssetEntityImageProvider(
      await AssetEntity.fromId(retrEnt.localId),  // <--- HERE is the issue
      isOriginal: false,
      thumbnailSize: const ThumbnailSize.square(200),
      thumbnailFormat: ThumbnailFormat.jpeg,
    ),
  )

to:

for (var retrEnt in snapshot.data!) 
  FutureBuilder<AssetEntity?>(
    future: AssetEntity.fromId(retrEnt.localId.toString()),
    builder: (contextPics, snapshotPics) {
      if (snapshotPics.hasData) {
        return AssetEntityImage(
          snapshotPics.data!,
          isOriginal: false,
          thumbnailSize: const ThumbnailSize.square(200),
          thumbnailFormat: ThumbnailFormat.jpeg,
        );
      } else if (snapshot.hasError) {
        return Text('${snapshotPics.error}');
      }
      // By default, show a loading spinner.
      return const CircularProgressIndicator();
    }

  ),