How to create this rounded offset rectangle in flutter - flutter

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

Related

Animation only works when the window is resized

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.

How can I draw a widget on top of a widget in flutter?

I want to draw a yellow arrow over the 9 blue squares as shown in the picture below.
But I don't know which widget to use to draw arrows freely on each rectangle. I want to draw an arrow like a screen lock pattern. I would like to know the different ways in which this arrow can be implemented.
You can put the whole Containers inside a Stack widget and then paint the line by using the CustomPaint widget shown in this question Draw lines with flutter.
Stack(
children: [
Arrow(child: Container()),
ContainerWidgets(),
],
)
And for the painter:
class Arrow extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
// Add your paint logic here
}
}

how to use shouldRepaint properly in flutter CustomPaint

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;
}
}

How do you clip GestureDetector (or InkWell) input Area with a path?

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

Flutter: Is it possible to auto-scale (whole) ui based on device size?

iOS native apps auto-scale the whole ui based on device size (width). Is there a similar behaviour with flutter?
I want to design a ui (with font sizes, paddings, etc) for a master device (iphone xs) and scale the whole ui to all other devices.
Wondering if that is possible as i couldn't find any information about it.
Just responsive sizing that needs me to configure breakpoints etc.
I usually obtain device size on Widget build, and then use a fraction of the width and height for each widget: Something like this:
import 'package:flutter/material.dart';
Size deviceSize;
class Welcome extends StatefulWidget {
WelcomeState createState() => WelcomeState();
}
class WelcomeState extends State<Welcome> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
deviceSize = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: color3,
body: Container(
height:deviceSize.height*0.5,
width:deviceSize.width-50.0,
child: Text("Welcome"),
),
);
}
}
Yes, this indeed is possible. All you need is a ratio-scaling approach with which you scale your entire GUI. Check out this ratio-scaling solution given to another SO answer relating to the Flutter UI scaling issue.
It's better to use MediaQuery.of(context).size, because while using external package, you won't be able to maintain the size of widgets on orientation change which might be a big downfall if your application required orientation change for better visual effects:
Widget build(BuildContext context) {
AppBar appBar = AppBar(title: const Text("My Dashboard"));
height = MediaQuery.of(context).size.height -
appBar.preferredSize.height -
MediaQuery.of(context).padding.top; // for responsive adjustment
width = MediaQuery.of(context).size.width; // for responsive adjustment
debugPrint("$height, width: ${MediaQuery.of(context).size.width}");
return Scaffold(appBar: appBar, body: ResponsivePage(height,width));
}
Check out this package:
https://pub.dev/packages/scaled_app
Replace runApp with runAppScaled, the entire UI design will be scaled automatically.
Helpful when you want adapt to different screen sizes quickly