Как нарисовать пользовательскую изогнутую форму динамической высоты в flutter?

#android #flutter #dart #widget #flutter-layout

#Android #flutter #dart #виджет #flutter-layout

Вопрос:

Я хочу нарисовать пользовательскую форму ниже типа в flutter

введите описание изображения здесь

До сих пор я пытался использовать CustomPainter

 class MyBottomPainter extends CustomPainter {
  final Color color;

  MyBottomPainter(this.color);

  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = color ?? Colors.black.withOpacity(0.7)
      ..style = PaintingStyle.fill;

    var rect = Rect.fromCircle(
        center: Offset(size.width * 0.110, size.height * 0.835), radius: 40.0);

    var path = Path()
      ..moveTo(0, size.height * 0.875)
      ..addArc(rect, 0, size.width * 0.100)
      ..quadraticBezierTo(
          0, size.height * 0.875, size.width * 0.100, size.height * 0.675)
      ..quadraticBezierTo(size.width * 0.100, size.height * 0.675,
          size.width - 40.0, size.height * 0.675)
      ..quadraticBezierTo(size.width, size.height * 0.645, size.width,
          size.height * 0.675 - 40.0)
      ..lineTo(size.width, size.height)
      ..lineTo(0, size.height);

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
  

Я также пытался использовать ShapeBorder

 class BottomShapeBorder extends ShapeBorder {
  const BottomShapeBorder();

  @override
  Path getInnerPath(Rect rect, {TextDirection textDirection}) => _getPath(rect);

  @override
  Path getOuterPath(Rect rect, {TextDirection textDirection}) => _getPath(rect);

  _getPath(Rect rect) {
    final r = rect.height / 2;
    final radius = Radius.circular(r);
    final offset = Rect.fromCircle(center: Offset.zero, radius: r);
    return Path()
      ..moveTo(rect.topLeft.dx, rect.topLeft.dy)
      ..relativeArcToPoint(offset.bottomLeft, clockwise: false, radius: radius)
      ..relativeArcToPoint(offset.bottomRight, clockwise: true, radius: radius)
      ..relativeArcToPoint(offset.topRight, clockwise: true, radius: radius)
      ..lineTo(rect.centerRight.dx - r, rect.centerRight.dy)
      ..relativeArcToPoint(offset.topRight, clockwise: false, radius: radius)
      ..addRect(rect);
  }

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

  @override
  ShapeBorder scale(double t) {
    return BottomShapeBorder();
  }

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

Но я не получаю ожидаемого результата, используя оба подхода

кто-нибудь может помочь мне создать этот тип пользовательской формы?

Если вам нужна дополнительная информация, пожалуйста, дайте мне знать. Заранее спасибо. Ваши усилия будут оценены по достоинству.

Комментарии:

1. вы просто хотите Path или как сделать этот эффект тумана?

2. @pskink я просто хочу сделать Path с динамической высотой в соответствии с содержанием

3. @override Path getOuterPath(Rect rect, {ui.TextDirection textDirection}) { final RADIUS = 64.0; var r = Radius.circular(RADIUS); var rect0 = EdgeInsets.only(top: RADIUS).deflateRect(rect); var rrect = RRect.fromRectAndCorners(rect0, topLeft: r, bottomLeft: r, bottomRight: r); return Path() ..moveTo(rect.topRight.dx, rect.topRight.dy) ..arcToPoint(rect.topRight Offset(-RADIUS, RADIUS), radius: r) ..relativeLineTo(RADIUS, 0) ..addRRect(rrect); }

4. @pskink можете ли вы оставить комментарий выше в качестве ответа на то, как я использую приведенный выше код?

5. это переопределенный getOuterPath метод — просто замените его своей версией

Ответ №1:

Для этого вы можете использовать оформление контейнера

 Container(
    decoration: BoxDecoration(
              color: Color.black,
              borderRadius: BorderRadius.only(
                bottomLeft: Radius.circular(20),
                bottomRight: Radius.circular(20),
              )),
)