Как нарисовать пользовательский прямоугольник с закругленными углами (ShapeBorder) в Flutter? - PullRequest
0 голосов
/ 07 мая 2018

Я пытаюсь расширить класс ShapeBorder, чтобы добавить некоторые функциональные возможности. Но просто поиграв с методом paint, я нашел то, чего не ожидал:

enter image description here Углы границы и углы прямоугольника не совпадают. Я использовал следующий код:

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

И создал прямоугольник следующим образом:

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"),),
            ),

Мне кажется, что исходный код Flutter использует аналогичный подход, но, возможно, я чего-то не вижу.

EDIT Изменяя 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);
  }

Я все еще озадачен тем, как это сделать ...

Ответы [ 4 ]

0 голосов
/ 06 мая 2019

Рисование произвольно округленной границы с тенью.

new Container(

                decoration:
                new BoxDecoration(
                  borderRadius: new BorderRadius.circular(10.0),
                  color: Colors.white,

                  boxShadow: [
                    new BoxShadow(
                        color: Colors.grey,
                        blurRadius: 3.0,
                        offset: new Offset(1.0, 1.0))
                  ],
                ),
)

Рисование произвольно округленной границы без тени.

new Container(
        decoration:
                new BoxDecoration(
                  borderRadius: new BorderRadius.circular(10.0),
                  color: Colors.grey,


                ),
)
0 голосов
/ 27 июля 2018

Вы можете использовать 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);
0 голосов
/ 17 марта 2019

Вы можете использовать ClipRReact виджет вместо drawReact, и он прост в использовании.

ClipRRect(
        borderRadius: BorderRadius.circular(10),
        child: Container(),
      ),
0 голосов
/ 04 июня 2018

Вы должны использовать canvas.drawPath, а не drawRect

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

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

также, если вы просто хотите создать рамку, достаточно использовать

 @override
  Path getInnerPath(Rect rect, {TextDirection textDirection}) {
    return new Path()
      ..fillType = PathFillType.evenOdd
      ..addPath(getOuterPath(rect), Offset.zero);
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...