How to draw a custom rectangle with border radius in Flutter? - flutter

My UI draw like this picture:
So I write some code by using CodePainter in Flutter. Here's my code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class BackgroundShape extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
final Paint paint = Paint();
paint.color = Colors.black;
var smallRect = Alignment.bottomCenter.inscribe(Size(100, 50), Rect.fromLTWH(size.width/2 -35, size.height-40, 40, 30));
var path = Path();
path.fillType = PathFillType.evenOdd;
path.addRRect(RRect.fromRectAndCorners(Rect.fromLTWH(0, 0, size.width, size.height), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)));
path.addRRect(RRect.fromRectAndCorners(smallRect, topLeft: Radius.circular(10), topRight: Radius.circular(10)));
path.lineTo(0, size.height);
path.lineTo(size.width/2 - 35, size.height);
path.lineTo(size.width/2 - 35, size.height-40);
path.lineTo(size.width/2 + 35, size.height-40);
path.lineTo(size.width/2 + 35, size.height);
path.lineTo(size.width, size.height);
path.lineTo(size.width, 0);
path.close();
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
Here is my result:
How to add border radius? please help me :D thanks!

For some reason, I'm not able to run completely the code you've provided, but taking consideration your current requirements and from the comments. I've created the following samples for your references:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo'),
),
body: Center(
child: Container(
width: 200,
height: 200,
child: CustomPaint(
painter: PainterTwo(),
),
),
),
);
}
}
class PainterOne extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
double w = size.width;
double h = size.height;
double r = 15;
var paint1 = Paint()
..color = Color(0xff888888)
..style = PaintingStyle.fill;
RRect fullRect = RRect.fromRectAndRadius(
Rect.fromCenter(center: Offset(w / 2, h / 2), width: w, height: h),
Radius.circular(r),
);
canvas.drawRRect(fullRect, paint1);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
class PainterTwo extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Colors.blue
..style = PaintingStyle.stroke
..strokeWidth = 8.0;
Path path = Path();
path.addRRect(RRect.fromRectAndRadius(
Rect.fromLTWH(
size.width / 2, size.height / 2, size.width / 4, size.height / 4),
Radius.circular(15)));
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
Output of PainterOne():
Output of PainterTwo():

Related

how to create cove of top of Container and add image inside of CustomPainter in flutter app

how to add image inside of CustomPainter and manage.
like this:
import 'package:flutter/material.dart';
import 'package:hallo/appbar.dart';
class product1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body:Stack(
children: [
Column(
children: [
CustomPaint(
size: Size.fromHeight(500),
painter: RPSCustomPainter(),
),
Container(
)
],
)
],
)
);
}
}
class RPSCustomPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
Paint paint0 = Paint()
..color = const Color.fromARGB(255, 33, 150, 243)
..style = PaintingStyle.stroke
..strokeWidth = 1.0;
Path path0 = Path();
path0.moveTo(0,0);
path0.lineTo(0,size.height);
path0.quadraticBezierTo(size.width*0.1120000,size.height*0.7968571,size.width*0.3375000,size.height*0.8585714);
path0.cubicTo(size.width*0.5795625,size.height*0.9350714,size.width*0.8043750,size.height*1.0775000,size.width,size.height);
path0.quadraticBezierTo(size.width,size.height*0.7500000,size.width,0);
path0.lineTo(size.width*0.1252500,0);
path0.lineTo(0,0);
path0.close();
canvas.drawPath(path0, paint0);
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
try this:
class HomeScreen extends StatelessWidget {
const HomeScreen({
super.key,
});
static const String route = "/homeScreen";
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Container(
height: MediaQuery.of(context).size.height * 0.5,
child: Image.network(
"https://images.pexels.com/photos/14446269/pexels-photo-14446269.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
fit: BoxFit.cover,
width: double.infinity,
),
),
CustomPaint(
size: MediaQuery.of(context).size,
painter: RPSCustomPainter(),
),
],
),
);
}
}
class RPSCustomPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
Paint paint0 = Paint()
..color = const Color.fromARGB(255, 33, 150, 243)
..style = PaintingStyle.fill
..strokeWidth = 5.0;
Path path1 = Path();
path1.moveTo(0, size.height);
path1.lineTo(0, size.height * 0.5);
path1.quadraticBezierTo(
size.width * 0.1120000,
size.height * 0.5 * 0.7968571,
size.width * 0.3375000,
size.height * 0.5 * 0.8585714);
path1.cubicTo(
size.width * 0.5795625,
size.height * 0.5 * 0.9350714,
size.width * 0.8043750,
size.height * 0.5 * 1.0775000,
size.width,
size.height * 0.5,
);
path1.lineTo(size.width, size.height);
path1.lineTo(0, size.height);
path1.close();
canvas.drawPath(path1, paint0);
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
you will get this type of results:

How can I draw a diagonal line inside a container?

The container has an image as a child. I need a line on top of that (diagonally from top right to bottom left).
Use a CustomPainter
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 40, vertical: 80),
child: Container(
width: 300,
height: 400,
color: Colors.yellow,
child: CustomPaint(painter: LinePainter()),
),
),
),
);
}
}
class LinePainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
final p1 = Offset(size.width, 0);
final p2 = Offset(0, size.height);
final paint = Paint()
..color = Colors.black
..strokeWidth = 4;
canvas.drawLine(p1, p2, paint);
}
#override
bool shouldRepaint(LinePainter oldDelegate) => false;
}
You need to use clippath To do that
like this
class CustomClipPath extends CustomClipper<Path> {
var radius=10.0;
#override
Path getClip(Size size) {
Path path = Path();
path.lineTo(0, 200);
path.lineTo(200,200);
path.lineTo(260,0);
path.lineTo(30, 0);
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

Flutter : How to draw a vertical sine wave inside a container?

How can I draw something like this inside a container in flutter?.
PS I am new to flutter.
Thanks in advance.
You can try this, the idea is using multiple quadraticBezierTo. Remember that B, C, D should be on the same line to make the joint smooth:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Container(
width: 300,
height: 700,
color: Colors.yellow,
child: CustomPaint(painter: FaceOutlinePainter()),
),
),
),
);
}
}
class FaceOutlinePainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 8.0;
Path path = Path();
path.moveTo(size.width / 2, 0); //Ax, Ay
path.quadraticBezierTo(size.width, size.height / 8, size.width / 2, size.height / 4); //Bx, By, Cx, Cy
path.quadraticBezierTo(0, 3 * size.height / 8, size.width / 2, size.height / 2); //Dx, Dy, Ex, Ey
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(FaceOutlinePainter oldDelegate) => false;
}

Draw a line with Scaffold widget

My goal is to draw a line, however, it is not working.
I find out that the size parameter in paint function is always 0
why ? what should I change in order to make it works
class CurvePainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.color = Colors.green[800];
paint.style = PaintingStyle.stroke;
paint.strokeWidth = 2.0;
var path = Path();
path.lineTo(size.width, size.height);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
class Home extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: Center(child: CustomPaint(painter: CurvePainter)),
);
You can copy paste run full code beow
Step 1 : You can wrap with Container to provide size
Step 2 : You need path.close() and canvas.drawPath()
Step 3 : CurvePainter typo need CurvePainter(), you loss ()
code snippet
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.color = Colors.green[800];
paint.style = PaintingStyle.stroke;
paint.strokeWidth = 2.0;
var path = Path();
print(size.height);
path.lineTo(size.width, size.height);
path.close();
canvas.drawPath(path, paint);
}
...
body: Center(
child: Container(
width: 100,
height: 100,
child: CustomPaint(painter: CurvePainter())))
working demo
full code
import 'package:flutter/material.dart';
class CurvePainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.color = Colors.green[800];
paint.style = PaintingStyle.stroke;
paint.strokeWidth = 2.0;
var path = Path();
print(size.height);
path.lineTo(size.width, size.height);
path.close();
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Home(),
);
}
}
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: Center(
child: Container(
width: 100,
height: 100,
child: CustomPaint(painter: CurvePainter()))),
);
}
}

Custom gauge chart in Flutter

I want to create something like this:
How can I do that in flutter? I can't find any similar lib for that.
You can create a custom CircularProgressIndicator using CustomPainter.
class CustomCircularProgress extends CustomPainter {
final double value;
CustomCircularProgress({required this.value});
#override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
canvas.drawArc(
Rect.fromCenter(center: center, width: 170, height: 170),
vmath.radians(140),
vmath.radians(260),
false,
Paint()
..style = PaintingStyle.stroke
..color = Colors.black12
..strokeCap = StrokeCap.round
..strokeWidth = 20,
);
canvas.saveLayer(
Rect.fromCenter(center: center, width: 200, height: 200),
Paint(),
);
const Gradient gradient = SweepGradient(
startAngle: 1.25 * math.pi / 2,
endAngle: 5.5 * math.pi / 2,
tileMode: TileMode.repeated,
colors: <Color>[
Colors.blueAccent,
Colors.lightBlueAccent,
],
);
canvas.drawArc(
Rect.fromCenter(center: center, width: 170, height: 170),
vmath.radians(140),
vmath.radians(260 * value),
false,
Paint()
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round
..shader = gradient
.createShader(Rect.fromLTWH(0.0, 0.0, size.width, size.height))
..strokeWidth = 20,
);
canvas.restore();
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
Then use CustomPaint to render the CustomPainter on the Screen.
CustomPaint(painter: CustomCircularProgress(value: 0.75))
Complete Sample
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math.dart' as vmath;
import 'dart:math' as math;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
late AnimationController controller;
#override
void initState() {
controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 5),
)..addListener(() {
setState(() {});
});
controller.repeat(reverse: true);
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: CustomPaint(painter: CustomCircularProgress(value: controller.value)),
),
);
}
}
class CustomCircularProgress extends CustomPainter {
final double value;
CustomCircularProgress({required this.value});
#override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
canvas.drawArc(
Rect.fromCenter(center: center, width: 170, height: 170),
vmath.radians(140),
vmath.radians(260),
false,
Paint()
..style = PaintingStyle.stroke
..color = Colors.black12
..strokeCap = StrokeCap.round
..strokeWidth = 20,
);
canvas.saveLayer(
Rect.fromCenter(center: center, width: 200, height: 200),
Paint(),
);
const Gradient gradient = SweepGradient(
startAngle: 1.25 * math.pi / 2,
endAngle: 5.5 * math.pi / 2,
tileMode: TileMode.repeated,
colors: <Color>[
Colors.blueAccent,
Colors.lightBlueAccent,
],
);
canvas.drawArc(
Rect.fromCenter(center: center, width: 170, height: 170),
vmath.radians(140),
vmath.radians(260 * value),
false,
Paint()
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round
..shader = gradient
.createShader(Rect.fromLTWH(0.0, 0.0, size.width, size.height))
..strokeWidth = 20,
);
canvas.restore();
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}