Border at corner only in flutter
566
This can be done with CustomPaint
widget with CustomPainter set as foregroundPainter
:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'CustomPaint spotlight',
home: Scaffold(
appBar: AppBar(
title: Text('CustomPaint spotlight'),
),
body: Center(
child: CustomPaint(
foregroundPainter: BorderPainter(),
child: Container(
width: 200,
height: 100,
color: Colors.deepOrange[50],
),
),
),
),
);
}
}
class BorderPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
double sh = size.height; // for convenient shortage
double sw = size.width; // for convenient shortage
double cornerSide = sh * 0.1; // desirable value for corners side
Paint paint = Paint()
..color = Colors.black
..strokeWidth = 1.5
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
Path path = Path()
..moveTo(cornerSide, 0)
..quadraticBezierTo(0, 0, 0, cornerSide)
..moveTo(0, sh - cornerSide)
..quadraticBezierTo(0, sh, cornerSide, sh)
..moveTo(sw - cornerSide, sh)
..quadraticBezierTo(sw, sh, sw, sh - cornerSide)
..moveTo(sw, cornerSide)
..quadraticBezierTo(sw, 0, sw - cornerSide, 0);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(BorderPainter oldDelegate) => false;
@override
bool shouldRebuildSemantics(BorderPainter oldDelegate) => false;
}
This produces the result like:
You need to know that CustomPaint does not crop its child corners and in some cases that might be discouraging. You have two ways of solving this:
-
Easy one - to cast rounded borders on its child and make them be visibly equal to CustomPaint borders.
-
Robust one - to wrap child with
ClipPath
with a path that copies CustomPaint path
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'CustomPaint spotlight',
home: Scaffold(
appBar: AppBar(
title: Text('CustomPaint spotlight'),
),
body: Center(
child: CustomPaint(
foregroundPainter: BorderPainter(),
child: ClipPath(
clipper: BorderClipper(),
child: Container(
width: 200,
height: 100,
color: Colors.deepOrange[50],
),
),
),
),
),
);
}
}
class BorderPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
double sh = size.height; // for convenient shortage
double sw = size.width; // for convenient shortage
double cornerSide = sh * 0.1; // desirable value for corners side
Paint paint = Paint()
..color = Colors.black
..strokeWidth = 1.5
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
Path path = Path()
..moveTo(cornerSide, 0)
..quadraticBezierTo(0, 0, 0, cornerSide)
..moveTo(0, sh - cornerSide)
..quadraticBezierTo(0, sh, cornerSide, sh)
..moveTo(sw - cornerSide, sh)
..quadraticBezierTo(sw, sh, sw, sh - cornerSide)
..moveTo(sw, cornerSide)
..quadraticBezierTo(sw, 0, sw - cornerSide, 0);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(BorderPainter oldDelegate) => false;
@override
bool shouldRebuildSemantics(BorderPainter oldDelegate) => false;
}
class BorderClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
double sh = size.height; // for convenient shortage
double sw = size.width; // for convenient shortage
double cornerSide = sh * 0.1;
Path path = Path()
..moveTo(cornerSide, 0)
..quadraticBezierTo(0, 0, 0, cornerSide)
..moveTo(0, sh - cornerSide)
..quadraticBezierTo(0, sh, cornerSide, sh)
..moveTo(sw - cornerSide, sh)
..quadraticBezierTo(sw, sh, sw, sh - cornerSide)
..moveTo(sw, cornerSide)
..quadraticBezierTo(sw, 0, sw - cornerSide, 0);
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
Author by
Farhana Naaz Ansari
Farhana... The only way of writing fewer bugs is writing less code.
Updated on December 28, 2022Comments
-
Farhana Naaz Ansari over 1 year
I trying to make border at corner only in container.
Container( padding: const EdgeInsets.only(right: 8.0, left: 8.0), height: 60, child: Card( elevation: 2, shape: RoundedRectangleBorder( side: BorderSide(color: appThemeColor.shade200, width: 0.5), borderRadius: BorderRadius.circular(5)), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[ Container( decoration: BoxDecoration( borderRadius: BorderRadius.only( topRight: Radius.circular(15), bottomRight: Radius.circular(15)), color: Colors.deepPurple, ), width: 5, ), ], ), ), )
-
Simon Sot about 3 yearsLet me clarify a bit. You want painted corners like on image?
-
Farhana Naaz Ansari about 3 years@SimonSot just need painted corner.
-
Simon Sot about 3 yearsI get it. This is easily done with
CustomPaint
widget. Do you want me to code it for you? -
Farhana Naaz Ansari about 3 years@SimonSot yes, i don't have much knowledge of custom paint.
-
-
Farhana Naaz Ansari about 3 yearsThank you! for your answer.