How to draw a custom rounded rectangle border (ShapeBorder), in Flutter?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


How to draw a custom rounded rectangle border (ShapeBorder), in Flutter?



I'm trying to extend the ShapeBorder class to add some functionality. But just playing around with the paint method, I found something that I did not expect:


ShapeBorder


paint



enter image description here
The corners of the border and the corners of the rectangle do not seem to match. I used the following code:


class CustomRoundedRectangleBorder extends ShapeBorder {

final double borderWidth;
final BorderRadius borderRadius;

const CustomRoundedRectangleBorder({
this.borderWidth: 1.0,
this.borderRadius: BorderRadius.zero,
})
: assert(borderRadius != null);

@override
EdgeInsetsGeometry get dimensions {
return new EdgeInsets.all(borderWidth);
}

@override
ShapeBorder scale(double t) {
return new CustomRoundedRectangleBorder(
borderWidth: borderWidth * (t),
borderRadius: borderRadius * (t),
);
}

@override
ShapeBorder lerpFrom(ShapeBorder a, double t) {
assert(t != null);
if (a is CustomRoundedRectangleBorder) {
return new CustomRoundedRectangleBorder(
borderWidth: ui.lerpDouble(a.borderWidth, borderWidth, t),
borderRadius: BorderRadius.lerp(a.borderRadius, borderRadius, t),
);
}
return super.lerpFrom(a, t);
}

@override
ShapeBorder lerpTo(ShapeBorder b, double t) {
assert(t != null);
if (b is CustomRoundedRectangleBorder) {
return new CustomRoundedRectangleBorder(
borderWidth: ui.lerpDouble(borderWidth, b.borderWidth, t),
borderRadius: BorderRadius.lerp(borderRadius, b.borderRadius, t),
);
}
return super.lerpTo(b, t);
}

@override
Path getInnerPath(Rect rect, { TextDirection textDirection }) {
return new Path()
..addRRect(borderRadius.resolve(textDirection).toRRect(rect).deflate(
borderWidth));
}

@override
Path getOuterPath(Rect rect, { TextDirection textDirection }) {
return new Path()
..addRRect(borderRadius.resolve(textDirection).toRRect(rect));
}

@override
void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) {
rect = rect.deflate(borderWidth / 2.0);

Paint paint;
final RRect borderRect = borderRadius.resolve(textDirection).toRRect(rect);
paint = new Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = borderWidth;
canvas.drawRRect(borderRect, paint);
}
}



And created the rectangle as follows:


new Container(
height: 100.0,
width: 200.0,
padding: new EdgeInsets.all(10.0),
decoration: new ShapeDecoration(
color: Colors.black,
shape: new CustomRoundedRectangleBorder(
borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
borderWidth: 10.0,
),
// side: new BorderSide(color: Colors.white)
),
child: new Center(child: new Text("My Button"),),
),



I feel like the Flutter source code takes a similar approach, but perhaps I'm not seeing something.



EDIT
Changing the style of my paint to PaintingStyle.fill thus drawing a rectangle over the original rectangle instead of borders, I do seem to get the correct borders:


style


paint


PaintingStyle.fill


void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) {

// rect = rect.deflate(borderWidth / 2.0);

Paint paint;
final RRect borderRect = borderRadius.resolve(textDirection).toRRect(rect);
paint = new Paint()
..color = Colors.red.withOpacity(0.25)
..style = PaintingStyle.fill
..strokeWidth = borderWidth;
canvas.drawRRect(borderRect, paint);
}



I'm still puzzled on how to do this...





I did find a solution for this. My code is too much of a mess to post and I don't have the time to clean it atm. But I'll post it once I find the time!
– Bram Vanbilsen
Jun 4 at 18:01




2 Answers
2



You should use canvas.drawPath not drawRect


Paint paint = new Paint()
..color = borderColor
..style = PaintingStyle.stroke
..strokeWidth = borderWidth;

canvas.drawPath(getOuterPath(rect), paint);



also if you just want a border, its enough to use


@override
Path getInnerPath(Rect rect, {TextDirection textDirection}) {
return new Path()
..fillType = PathFillType.evenOdd
..addPath(getOuterPath(rect), Offset.zero);
}





I actually got a really nice solution with drawRect. I'm very busy atm and the code is too much of a mess to share rn, but I'll post it when I find the time to clean it!
– Bram Vanbilsen
Jun 4 at 18:00


drawRect





@BramVanbilsen any update? Curious.
– seenickcode
Jul 11 at 13:09



You can use canvas.drawRRect :


canvas.drawRRect


canvas.drawRRect(RRect.fromRectAndRadius(Rect.fromLTWH(size.width / 2 - gap - smallMarkWidth - 15,gap * 8,gap + 70,gap * 5,),Radius.circular(15.0)),backgroundPaint);






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

C# - How to create a semi transparent or blurred backcolor on windows form

Swipe gestures in WKWebView

How to populate data on nav-tab in partial View in MVC?