flutter_photo_manager icon indicating copy to clipboard operation
flutter_photo_manager copied to clipboard

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

Open vlavorini opened this issue 1 year ago • 1 comments

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 avatar Oct 23 '24 07:10 vlavorini

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();
    }


  ),

vlavorini avatar Oct 23 '24 08:10 vlavorini

Yes, the current approach is to obtain the entity first, then the image provider.

AlexV525 avatar Oct 31 '24 15:10 AlexV525