Search code examples
flutterdartflutter-futurebuilderappwrite

Caching images (thumbnails) in Listview


I made a simple application where in listview I display a list of items by ListView.builder. Each item is a widget where by FutureBuilder I build a CircleAvatar with a picture taken in initState () via Api. I'm using the AppWrite API. The method returns the photo in the form of Uint8list. It's working fine.

 @override
  void initState() {

    super.initState();
    myFuture = AppWriteService.getImagePreview()
}
    FutureBuilder(
            future: myFuture ,
            builder: (context, snapshot) {
              print("build photo for:" +widget.doc.place!);
              //  print(snapshot.data);
              Uint8List? bytes = snapshot.data as Uint8List?;
              // print(bytes);
              return snapshot.hasData && snapshot.data != null
                  ? CircleAvatar(
                radius: 40,
                backgroundImage: MemoryImage(bytes!),
              )
                  : CircularProgressIndicator();
            },
          )

However, I wanted the whole list to not refresh after removing one item, I mean, it can build, but I would not like the fetch method to download photos for previously displayed items to be performed again. Now, when you delete an item, the whole list refreshes and the photos are downloaded again by fetch method for all elements.

I have already made the another solution, but I have doubts if it is good. After downloading the items, before I build the list, I download a photo for each item and save it as bytes in my object. so each item already "holds" a photo and there is no need to use FutureBuilder. So first I get all elements by first request fetchAll() and then in loop for every element I run getImagePreview() and then I build a ListView

I would be grateful for your tips which solution is better.


Solution

  • If you really want to use cached_network_image, you can. You'll just have to manually build the URL yourself:

    CachedNetworkImage(
      imageUrl: '${client.endPoint}/storage/buckets/${bucketId}/files/${fileId}/view',
      httpHeaders: {
        'X-Appwrite-Project': widget.client.config['project']!,
      },
    )
    

    If your file isn't public, you'll also need to generate a JWT token via account.getJWT() and then pass in the headers:

    CachedNetworkImage(
      imageUrl: '${client.endPoint}/storage/buckets/${bucketId}/files/${fileId}/view',
      httpHeaders: {
        'X-Appwrite-Project': widget.client.config['project']!,
        'X-Appwrite-JWT': jwt,
      },
    )