Flutter CustomPainter paint behavoir and performance - flutter

I am learning and playing around with Flutter. Currently I am trying to reproduce an app I previously made with C# and WPF. In my Flutter app I have a list of Widgets extending CustomPainter. Now I am able to move/drag any of these widgets around the screen. What I see is that always when dragging one of this widgets all CustomPaint widgets are repainted. I checked what would happen if I decide to resize my window, and you can guess, all CustomPaint widgets are repainted.
I decided to create three different projects. One is using statefull widgets and setState to manage the state. The other is using Provider and the last one is using Riverpod. Still all Widgets extending CustomPainter are repainted when dragging a single Widget or resizing the window.
Now my question is, am I doing something wrong in my state management or is this behavior by default?
Also my C#/WPF app uses half the cpu the Flutter app uses when dragging one shape around. I did not expect such a difference. For now I did not make any complex CustomPaint obecjt in my flutter app. But should I expect a big performance reduction if I have many complex CustomPaint widgets?

am I doing something wrong in my state management or is this behavior
by default?
Yes and no. Widgets are rebuilt when the screen size changes, but dragging a widget should not make other widgets rebuild. You can try RepaintBoundary (https://api.flutter.dev/flutter/widgets/RepaintBoundary-class.html)
Should I expect a big performance reduction if I have many complex
CustomPaint widgets?
This has a lot to do with what kind of CustomPaint widgets you will be using and what is "many". You can test how long the CustomPaint widget's paint method takes, for example by using the profiler (https://docs.flutter.dev/perf/ui-performance). My assumption is that the efficiency decreases linearly as you add more CustomPaint widgets

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 to create a scrollView in Flutter Flame

I need a listView for my Game. Is there a simple way to create one? There are no tutorials for such a feature and I couldn't find anything in the documentation.
Flame doesn't provide their own widgets for these things, we rely on Flutters excellent widget system.
So you create the widget directly in Flutter and then you either put your GameWidget in a stack (or similar) and use Flutter's own Navigation to move between the widgets, or you use Flame's overlay system.
For using the overlays you add the overlays that you want to have accessible when you create the GameWidget and then you call game.overlays.add to render a specific widget, and game.overlays.remove to stop rendering it.

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

How to get a widget to move across the screen every X seconds?

Basically I'm trying to build a game to learn flutter more.
Right now I'm just trying to get a Text widget to move from the top of the phone screen, towards the bottom of the phone screen... I'm building a Space Invaders type of game with just Text.
From what I've read by googling the problem, should I use Flame? Or can everything be done by just using the base Flutter framework (collision detection, moving widgets, etc...)? Thanks.
You can use Draggable class for dragging the item.
A simple way to solve this problem is to have the moving Text widget a child of the Stack() widget. Actually, the child of the Stack() widget is a Positioned() widget, which has left and top properties, which you can update periodically with a Timer.periodic function to move the widget down by incrementing top property. So, your Text widget is a child of the Positioned() widget, that you use for, well, positioning.
I have a working example of this in my slowly_moving_widgets_field project, where I have a bunch of arbitrary widgets moving about the screen every X seconds as you desire.

Is it bad to have a lot of nested widgets with Flutter?

I have a strong background with Android development and I'm now trying to develop my first app with Flutter.
It is a common knowledge in the Android community that it's bad have too many nested views. It's bad for performance. (That's one of the reason why ConstraintLayout exists)
However, in Flutter tutorials I see that people nest a lot of widgets.
Could somebody confirm that it's not a problem to nest widgets with Flutter? Will my app suffer of bad performance if I do it?
Thanks in advance
TL;DR: Deeply nesting single-purpose widgets in Flutter is recommended.
There are fundamental differences in how Android and Flutter render view elements (aka widgets or views).
In Android, there are relatively few, complex views that inherit each other.
Each and every view provides a huge API surface, including stuff like padding, margin, colors etc.
Flutter, on the other hand, favors composition over inheritance.
Most widgets exist for a single purpose only and are very lightweight.
That means you need to nest widgets more deeply to achieve the same effects, but because their layout and rendering logic is easier, the rendering is typically faster.
For example, there's a Padding widget that makes some space around its child.
The Padding widget's rules are very simple, making the rendering very fast.
Additionally, the rules of every other widget also get simpler because they don't need to worry about padding anymore.
Basically, nesting widgets deeply is recommended in Flutter.
It's quite the opposite to Android's model:
If there's not much nesting, you probably did something wrong, because you have a huge widget that can often be split into simpler, faster, smaller widgets.
Here's an interesting Google Tech Talk about Flutter's rendering pipeline, which I recommend to anyone interested in this topic.
Nesting widgets is not a problem and is actually recommended.
In fact, the default counter application contains no less than 150 widgets.
Widgets are lightweight objects optimized specifically to create and destroy tons of them every frame. This is further prooved by Flutter FAQ:
Rather than having each widget provide a large number of parameters, Flutter embraces composition. Widgets are built out of smaller widgets that you can reuse and combine in novel ways to make custom widgets. For example, rather than subclassing a generic button widget, RaisedButton combines a Material widget with a GestureDetector widget. The Material widget provides the visual design and the GestureDetector widget provides the interaction design.
This quote says that you should purposefully nest widgets.