bluefireteam / photo_view

📸 Easy to use yet very customizable zoomable image widget for Flutter, Photo View provides a gesture sensitive zoomable widget. Photo View is largely used to show interacive images and other stuff such as SVG.
MIT License
1.91k stars 547 forks source link

How to handle Futures in PhotoViewGallery.builder ? #276

Open TheLastGimbus opened 4 years ago

TheLastGimbus commented 4 years ago

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?

renancaraujo commented 4 years ago

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.

TheLastGimbus commented 4 years ago

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 commented 4 years ago

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 :(

renancaraujo commented 4 years ago

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.

cherrybiu commented 4 years ago

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?

TheLastGimbus commented 4 years ago

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

github3t commented 4 years ago

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

renancaraujo commented 3 years ago

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.

TheLastGimbus commented 3 years ago

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?

github3t commented 3 years ago

@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.

TheLastGimbus commented 3 years ago

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:

renancaraujo commented 3 years ago

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

github3t commented 3 years ago

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

cherrybiu commented 3 years ago

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

renancaraujo commented 3 years ago

@github3t yes

purezen commented 2 years ago

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