title: How to draw a custom rounded rectangle border (ShapeBorder), in Flutter?
body: <p>I'm trying to extend the <code>ShapeBorder</code> class to add some functionality. But just playing around with the <code>paint</code> method, I found something that I did not expect: </p>
  
  <p><a href="https://i.stack.imgur.com/1xTJd.png" rel="noreferrer"><img src="https://i.stack.imgur.com/1xTJd.png" alt="enter image description here"></a>
  The corners of the border and the corners of the rectangle do not seem to match. I used the following code:</p>
  
  <pre><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);
    }
  }
  </code></pre>
  
  <p>And created the rectangle as follows:</p>
  
  <pre><code>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"),),
              ),
  </code></pre>
  
  <p>I feel like the Flutter source code takes a similar approach, but perhaps I'm not seeing something.</p>
  
  <p><strong>EDIT</strong>
  Changing the <code>style</code> of my <code>paint</code> to <code>PaintingStyle.fill</code> thus drawing a rectangle over the original rectangle instead of borders, I do seem to get the correct borders:</p>
  
  <pre><code>  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);
    }
  </code></pre>
  
  <p>I'm still puzzled on how to do this...</p>