Flutter: Build child depending on visibility - flutter

Assume I have an app where you can zoom in and out. The zooming is managed by a Transform Widget.
Now, if you zoom in, I want to load more details by expanding the Widget tree, and when zooming out I want to remove these too-tiny-to-be-seen Widgets again.
So, I’d like to have a fixed-size Widget that gets a lambda to build a child depending on:
- being seen on the screen
- actual pixel size

Related

Flutter increase performance of large number of Positioned Widgets on screen

I'm making a grid of hexagons by placing Positioned Widgets. I have them inside an Interactive Viewer Widget so I can zoom in and out and move around.
Issue I'm having however is that with a large number of them being rendered it's far too laggy. It's unusable with about 4000 rendered on screen and ideally I need 10s of thousands. And this has nothing to do with the Widget itself as it's the same when replaced with a SizedBox with a Container or Text in.
I am using an InteractiveViewer.builder and only render the Widgets on the screen, which works great and there's no lag when zoomed in with few widgets on the screen, however I need to zoom out and see more.
I've also run in release mode and it's the same. I'm running in Windows and my PC is more than capable, too capable compared to the phones this should also be able to run on.
Is there some way to increase performance, or some other way I should be doing this instead of thousands of Positioned Widgets? Or is Flutter just not suited for this?
Edit: Image.
Using a widget for each individual hexagon at that scale feels like massive overkill. If you're going to use flutter, maybe use a CustomPaint widget, which allows you to draw shapes directly to a pixel grid?
You could wrap it in a GestureDector and implement scrolling and zooming via that perhaps?

How would you make this simple flutter layout responsive?

A year has passed since last time I had to use flutter to build a little app for my firm. At that time MediaQuery was the trending way to create layouts ready for every screen size.
Today I am trying to build a simple layout like this one:
The part I am concerned about is the 3 circles in the middle. They have an icon and text inside and must be positioned at the positions seen in screen.
So, I have been investigating a bit how to create that part of the layout in a responsive way. I mean, that the circles are positioned at the correct position and size relative to the screen size and that the icon and text inside the circle are positioned and resized correctly too ,to avoid overflowing the circles.
Is the MediaQuery class still the only tool that can be used to build this kind of responsive layouts? Would you tackle this layout using a different method?
Yes MediaQuery is still heavily used, but Flutter has introduced some good widgets based on Orientation and Responsive Layouts:
OrientationBuilder - Builds different widget trees based on Orientation - For Example if the device is horizontal, you might see a Square instead of a Circle.
CustomMultiChildLayout - It can automatically decide how to size and position each child, as well as size the parent. Single widgets can be used CustomSingleChildLayout
Also when resizing text automatically I found Auto Size Text to be amazing

Reusing the same instance of a widget in a ListView

At first — I have a widget, it contains and plays a specific animation which state cannot be saved or interrupted because animation data comes from a web server permanently and this stream is important.
Second — I have a ListView.builder with 'infinite' list of Cards (simple cards, doesn't important in this situation, app's screen contains 5 of them at the same time).
The problem is: is it possible to set given animated widget on every 10-th position of the ListView using the same instance of it in order to save it's animation state and not recreate animated widget every time? It must be the same widget, the animation must continue — one widget's instance on the screen at the time.
I tried to use a Stack with the animated widget wrapped with Offstage widget on the upper layer and the ListView with 'gaps' on every 10-th position. So Animated widget lives permanently and when it goes out of the screen I 'turn it off' with Offstage. And when it should appear on scroll I 'switch it on' with Offstage. But it is very difficult to position animated widget and synchronize its position with a scroll position of the ListView. For this purpose I use a GlobalKey for every 'gap' in the ListView, define it's Render Rectangle to position my Animated widget on/in the given gap.
Any ideas to solve this task more elegant? Maybe it is possible to make some 'deep copy' or 'singleton' or keep it alive (somehow) in the ListView or use some slivers, and reuse the same instance of it again and again when it appears?

Flutter Hero-like transition in PageView

I have an image in one page of the PageView. I want to animate this image to the next page when i go to it, sort of like when you use Hero animations in navigator page transitions. Any ideas how this can be achieved?
In order to achieve an animation similar to the hero animation. Basically what we will implement is this, you will need 5 elements:
The initial global coordinates
The final coordinates
Initial widget size
Final widget size
The widget you want to animate
Now in order to create this animation that spans the 2 screens we will need to use the overlay that is present in flutter. link
Add to the Overlay the widget that is to be animated (Not the widget present on the screen, a new instance).
Position this overlay entry to be in the starting coordinate of the animation (The original widget's position).
Hide the original widget.
Create an animation that changes the x and y coordinates to the create the custom motion, this can be any curve, the simplest being a simple tween between the starting coordinate and the end coordinate.
Another animation that animates size change between the start and end size. This animation can be combined with the previous one. (One tween animation but the values are calculated manually)
After the animation is done, remove the overlay entry, and show the new widget. (This can be done as a timed operation or as a call back operation)
This is the most flexible between all of the available options since you have access to the widget in all of its states. However you must be very careful when using this method as it might cause a slowdown if not properly implemented.
This packages does what you want https://pub.dev/packages/coast
It is essentially taking the same approach as Flutter’s Hero and HeroController: Detect when a transition is started, search through the element trees of the source and target pages for the widgets marked for animation (heroes, crabs), pair them up based on their tags, and finally create an entry in an Overlay whose position and size is the interpolation between those on the source and target pages.

How to animate fullscreen photo transition on swipe, like in Telegram?

When you swipe vertically, image is dragged towards the swipe, with fading out animation of black background.
And after release, it smoothly returns to it's previous position on the screen, like Hero animation does.
How is it possible to recreate such an effect using Flutter? The same scenario, in fullscreen photo view.
photo_view package is desired for fullscreen, so it shouldn't interfere with zooming.
What you need is actually an out-of-the-box widget, and it's surprisingly easy to use. It's called Hero. Basically, you wrap the widget you want to animate like that in a Hero widget, with a specific tag string, and, when you navigate to another screen, you wrap the destination widget in another Hero with the same tag. An effect like the one you shared can be achieved by wrapping two widgets with the same photo with Heroes in different PageRoutes.
Check out this Flutter widget of the week video to get you started, and this Flutter.dev article for a more detailed explanation on Hero widgets.
Edit: I see you are looking for a more specific image-viewer behavior. Then, I suggest you use the photo_view package, which includes many functionalities to visualize images, including the hero transition with swipe-dow-to-dismiss behaviors, pinching to zoom, etc.
I found the solution.
To create such an animation, you should use extended_image package, which has SlideOutPage widget for creation of such transitions.