The problem is that the animation only works if you start resizing the window. Tried on windows, web, android. Used by StatefulWidget and SlideTransition. The class is complex enough to post this code here.
Has anyone experienced this/similar issue?
The first problem is when we pass new coordinates(x, y) data to CustomPaint we may need override method shouldRepaint in CustomPainter with value true:
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
The second problem is when we pass mutable data in widget and such widget is many. The data should be immutable.
Related
In shorter word, my question is how to call child's initState() again on parent's setState().
I need to reuse a widget class for multiple instances. I need the widgets to appear in turn like below where I can use setState() to switch between them.
bool showthefirstone = true;
#override
Widget build(BuildContext context) {
...
TheWidget it = showthefirstone ? TheWidget(...) : TheWidget(..);
...
}
The later one's initState() is not called. No problem showing them both together along at the same time. The issue only occurs upon setState().
For those who don't understand, this trigger the change
setState((){showthefirstone = !showthefirstone})
It's the same answer with different question. My question is more generic. At least works for my case.
https://stackoverflow.com/a/70789848/1297048
I am trying to create this shape but am struggling. Have tried using shape maker but am struggling also to make this shape. I also tried using path, but am unsure whether this will work.
Any suggestions?
what I am trying to achieve
With the help of CustomPainter we can draw any kind of custom button and container, Flutter gives you access to low-level graphics painting. Best of all, painting in Flutter is fast and efficient.
CustomPaint takes a painter argument of type CustomPainter, an abstract class from the Flutter APIs.
Container(
color: Colors.yellow,
child: CustomPaint(painter: FaceOutlinePainter()),
),
and in FaceOutlinePainter() class you can add the size , width , height and all other requirment.
class FaceOutlinePainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
// TODO: draw something with canvas
}
#override
bool shouldRepaint(FaceOutlinePainter oldDelegate) => false;
}
Here's a reference video, https://www.youtube.com/watch?v=AnKgtKxRLX4
I've used this few times and it worked pretty well
I was wondering about where to declare and initialize variables in the case of a StatefulWidget. There seem to be a couple of ways to do it, but are there differences, any guidelines, or best practice approaches for it?
I created the below sample, but can not find any differences except that when performing a hot reload, variable i loses its value and is back to zero again.
I read this, but it contains so many contradicting comments.
class Sample extends StatefulWidget {
int i=0;
late Object object1 = Get.put(Object());
#override
_SampleState createState() => _SampleState();
}
class _SampleState extends State<Sample> {
int j = 0;
late Object object2;
#override
void initState() {
i=5;
j=5;
object1.param="value123";
object2=Get.put(Object());
object2.param="value123";
}
#override
Widget build(BuildContext context) {
}
}
First, if you run your app on the emulator you can indeed find no differences. But, that observation is huge misleading!
Variables declared whether initialized or not inside the Widget class are not persisted in the case of widget recreation. StatefulWidgets (and all Widget subclasses) are thrown away and rebuilt whenever configuration changes. Luckily, you can force performing Widget recreation by performing a hot reload on the widget while you are testing your app. to ensure proper behavior.
If you want to declare variables that should persist (State data), make sure to put them inside the State class as int j in the above code example.
Use initState() for variables that you cannot initialize within the declaration statement.
Why then object1 retain its data?
Simply, because GetX will not recreate a new instance of Object if one already exists. It will return back the old instance every time the Widget is rebuilt. That's why no difference is perceived in the case of object1 and object2 places of declaration.
At the time of writing this answer, you have to manually call Get.delete<>() in order to dispose a controller if you are not using bindings.
Now I have a canvas of CustomPaint which draws a sketch, the sketch illustrates a basic 2D movement of "fluids" in pipe. The pipe is generated only once, but the fluid movement is controlled by user input.
I have a result that needs optimization. I used one CustomPaint class to draw both in one canvas, and it redraws everything each time the user changes input.
What I need is optimization, i.e. to draw the pipe part which does not change and only repaint the fluids each time the user changes input. That would be better for resources as things get more complex.
I don't know how to use shouldRepaint or whether it's gonna be useful.
Would it be possible to draw on two layers, keep one static and the other "updateable".
class PipeProfile extends CustomPainter {
FluidsData pipeData;
WellProfileData fluidsData;
PipeProfile({
#required this.pipeData Data,
#required this.fluidsData});
#override
void paint(Canvas canvas, Size size) {
cutomFunctionToDrawPipe(pipeData);
cutomFunctionToDrawFluids(fluidsData);
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
I've created a custom drawn widget using CustomPaint that has a path as an outline. But wrapping the widget in a GestureDetector makes the click area a rectangle around the whole canvas, Is there a way to clip the GestureDetector so that that click only works within the path?
You can implement the hitTest method from the CustomPainter, add your Path there and use the condition path.contains(position) to ensure the touch only covers the Path part.
class MyCustomPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return null;
}
#override
bool hitTest(Offset position) {
Path path = Path();
//add your lines/curves here
path.close();
return path.contains(position);
}
}
More info about bool hitTest(Offset position):
Called whenever a hit test is being performed on an object that is
using this custom paint delegate.
The given point is relative to the same coordinate space as the last
[paint] call.
The default behavior is to consider all points to be hits for
background painters, and no points to be hits for foreground painters.
Return true if the given position corresponds to a point on the drawn
image that should be considered a "hit", false if it corresponds to a
point that should be considered outside the painted image, and null to
use the default behavior.
I answered a similar question here: Flutter: What is the correct way to detect touch enter, move and exit on CustomPainter objects