photo_view icon indicating copy to clipboard operation
photo_view copied to clipboard

How to handle Futures in PhotoViewGallery.builder ?

Open TheLastGimbus opened this issue 4 years ago • 16 comments

Hi! I'm using photo_manager library to get photos from user's phone. The thing is, if I want to get some photo's file object, it returns a Future with it's file:

var photoFile = assetEntity.file; // Returns a Future
PhotoViewGalleryPageOptions(
    // How to pass this future here when it completes
    imageProvider: ?,
    ...
)

Could you add some support for it, or tell me how I should?

TheLastGimbus avatar Apr 22 '20 19:04 TheLastGimbus

You can solve futures on the body of the state and save de resolved file via setState(). In this way, you only instantiate PhotoViewGalleryPageOptions on the build method if there is a value on the

Here is an example:

class MyState extends State<MyWidget> {

  var myImage;

  void someMethod () async{
    //...
    final result = await assetEntity.file;
    setState(() {
      myImage = result;
    });
  }

  Widget build(ctx) {
    if(myImage == null) return Text("loading");
    // here you can instantiate photoview with myImage as providerl
  }
}

It is just a matter of separating concerns, photo view and its companion classes are about UI, the flow of solving this future is about data.

renancaraujo avatar Apr 23 '20 08:04 renancaraujo

Already tried this:

  1. PhotoViewGalleryPageOptions doesn't have many options of PhotoView, such as gaplessPlayback or loadingBuilder. Only way to get them is to have ...Options.customChild(). I've looked at your code, and It seems like we could just pass a normal PhotoView directly to builder (PhotoViewGalleryPageOptions is just used to build PhotoView). Why aren't we doing it??

  2. I tried approach with ..Options.customChild(). With heroAttributes set, images flicker when switching between imageProviders (between lightweight thumbnail form memory and fully loaded file - also to memory aka. Uint8List). Only way I was able to remove the flicker and keep hero animation was to build PhotoView as child of standard Hero, instead of passing heroAttributes. But that also gave me some weird hero behaviour, that you probably fixed with heroAttributes.

To summarize all of this: There is flicker when changing imageProvider if heroAttribues is set. Setting gaplessPlayback and loadingBuilder doesn't fix it

TheLastGimbus avatar Apr 23 '20 16:04 TheLastGimbus

Just tried to to make PageView with normal Image.memory(), and it also flickers. You fixed it with loadingBuilder :) But it doesn't fully work with heroAttributes :(

TheLastGimbus avatar Apr 23 '20 16:04 TheLastGimbus

Why aren't we doing it??

The params passed to each option is a subset of all photo_view options. Some of them (including the ones passed you said) are passed to the gallery itself.

renancaraujo avatar Aug 12 '20 22:08 renancaraujo

Hi! I'm using photo_manager library to get photos from user's phone. The thing is, if I want to get some photo's file object, it returns a Future with it's file:

var photoFile = assetEntity.file; // Returns a Future
PhotoViewGalleryPageOptions(
    // How to pass this future here when it completes
    imageProvider: ?,
    ...
)

Could you add some support for it, or tell me how I should?

Excuse me , how did you finally solve the problem?

cherrybiu avatar Sep 16 '20 03:09 cherrybiu

I don't remember, but it think I didn't/it was very poor. I will inform you if I ever do anything successful with it

TheLastGimbus avatar Sep 23 '20 09:09 TheLastGimbus

I wrap PhotoViewGallery in a FutureBuilder that resolves List<AssetEntity> into List<File> using the asset.file getter.

github3t avatar Nov 08 '20 02:11 github3t

Since there is no answer for a while, I am automatically closing this issue for the sake of organization. If there is any news on that, feel free to retake the discussion.

renancaraujo avatar Nov 15 '20 20:11 renancaraujo

I was just about to answer @cherrybiu (but yeah, you can probably close this):

I ditched PhotoGallery altogether, and used PageView.builder with normal PhotoViews inside. Every time when PhotoViews scale change, i check if it's initial, and if it's not, I lock the PageView with NoScrollingPhysics.

I don't have the code in front of me right now, so some names can be incorrect, but you get the idea - I can give you the precise code if you need it :+1:

Edit: Oh, and @github3t - since in my case I could face 10 000 images at once, I can't load them all from list (and you probably shouldn't too) - I resolve every one in builder and it works... fine.

photo_manager is weird and slow library, so it could be that actually resolving them all at once is more efficient :thinking: But I don't know :confused:

How long do they load in your case? How many have you tried?

TheLastGimbus avatar Nov 15 '20 21:11 TheLastGimbus

@TheLastGimbus I wrap the call to get a file in a FutureBuilder. This is pretty fast, and only needed first time as I cache the result. It only gets slow when you open the file. Per Android Q (API 29) the file path is your apps cache, not the original file path. Even if you get oroginFile. When you open the file for viewing the system starts to make a copy. In my case I am also displaying videos so it's even worse 😭 I ended up without photo_gallery also, as mixing it with a video player proved very problematic. Gesture detectors in various components bite each other.

github3t avatar Nov 16 '20 00:11 github3t

I wrap the call to get a file in a FutureBuilder

But... you resolve whole List, as you mentioned before, or do it individually? Does it work faster with whole List at once?

Per Android Q (API 29) the file path is your apps cache

Jeez, like, why the hell did this Chinese guy implemented this in that way :shrug:

Even if you get oroginFile

He added .relativePath property tho - but it doesn't give you /emulated/0 part, so it will break with sd cards

In my case I am also displaying videos so it's even worse :sob:

PhotoView.customChild works nice. Zooming on videos would be also nice feature :wink:

By the way - are you making somewhat of a gallery app? If so, (me too) you can hit me up somewhere, we could help each other :wink:

TheLastGimbus avatar Nov 16 '20 01:11 TheLastGimbus

You can go do further discussions about this on our discord server. I'm also curious about the approach for this issue.

renancaraujo avatar Nov 16 '20 04:11 renancaraujo

I found the discord server (I'm new to this stuff). Discuss on #photoview channel? Or do you have another suggestion?

github3t avatar Nov 17 '20 02:11 github3t

Thanks a lot, I'll try it as you said.

cherrybiu avatar Nov 17 '20 03:11 cherrybiu

@github3t yes

renancaraujo avatar Nov 17 '20 09:11 renancaraujo

I am also looking to display images for which I am currently using PhotoViewGallery

However since the number of images can be quite large, feeding all images to the gallery is slowing it down considerably. Am curious as to how did you decide to go about it.

P.S.: I am also using photo_manager library to retrieve the pictures

purezen avatar Jan 22 '22 11:01 purezen