1

I wonder if there is a better solution for making a curved bar like the following image.

enter image description here

Here is my flutter code:

import 'package:flutter_web/material.dart';

class CurvedBar extends StatelessWidget {
    const CurvedBar({
      Key key,
    }) : super(key: key);

    @override
    Widget build(BuildContext context) {
      return Container(height: 50,
      color: Colors.orange,
      child:  Column(
        children: <Widget>[
          ClipRRect(
            borderRadius: BorderRadius.only(
                bottomLeft: Radius.circular(20.0),
                bottomRight: Radius.circular(20.0)),
            child: Container(
              height: 20.0,
              width: double.infinity,
              color: Colors.white,
            ),
          ),
         Container(
           color: Colors.white,
           child:  Row( 
            children: <Widget>[
              Flexible(
                  flex: 1,
                  child: ClipRRect(
                    borderRadius:
                        BorderRadius.only(topRight: Radius.circular(20.0)),
                    child: Container(
                      height: 20.0,
                      color: Colors.orange,
                    ),
                  )),
              Flexible(
                  flex: 1,
                  child: ClipRRect(
                    borderRadius:
                        BorderRadius.only(topLeft: Radius.circular(20.0)),
                    child: Container(
                      height: 20.0,
                      color: Colors.orange,
                    ),
                  ))
            ],
          ))
        ],
      ));
    }
  }
2
  • 1
    use a custom ShapeBorder (a class that extends ShapeBorder)? Commented Jun 23, 2019 at 11:50
  • @pskink I checked samples of this class but I still don't know how to achieve the same result Commented Jun 23, 2019 at 13:51

1 Answer 1

4

make a custom ShapeBorder class like this one (the key method is _getPath that returns your shape's Path):

class CustomShapeBorder extends ShapeBorder {
  const CustomShapeBorder();

  @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.bottomRight, clockwise: false, radius: radius)
      ..lineTo(rect.center.dx - r, rect.center.dy)
      ..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 CustomShapeBorder();
  }

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

now you can use it like:

    Container(
      margin: EdgeInsets.only(top: 80),
      height: 50,
      width: double.infinity,
      decoration: ShapeDecoration(
        shape: CustomShapeBorder(),
        //color: Colors.orange,
        gradient:
            LinearGradient(colors: [Colors.blue, Colors.orange]),
        shadows: [
          BoxShadow(
              color: Colors.black, offset: Offset(3, -3), blurRadius: 3),
        ],
      ),
    ),

Result:

enter image description here

Sign up to request clarification or add additional context in comments.

6 Comments

@pspkink how did you figure out the solution... I mean what I need to learn to be able to make any custom shape I imagine ?
well done!! - it seems that you implemented rest of the methods...the result looks pretty nice, doesn't it? btw i dont understand paint method in ShapeBorder as it seems that even with empty paint method body the shape is drawn!! and how i figure out the solution? it is simple Path manipulations... ;-)
ok, it seems i got it now: paint() is called after the shape is drawn so that you can draw some extra stuff on top of it
yes I got a better idea..by the way, my original screenshot is flutter web
and does CustomShapeBorder work on flutter web? i tested it on flutter (linux) desktop ;-)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.