user5182503
user5182503

Reputation:

How to set the color of PopupMenuButton border with custom shape?

In this answer I found a great solution how to make PopupMenuButton with tooltip shape. Here is the solution:

class TooltipShape extends ShapeBorder {
  const TooltipShape();

  final BorderSide _side = BorderSide.none;
  final BorderRadiusGeometry _borderRadius = BorderRadius.zero;

  @override
  EdgeInsetsGeometry get dimensions => EdgeInsets.all(_side.width);

  @override
  Path getInnerPath(
    Rect rect, {
    TextDirection? textDirection,
  }) {
    final Path path = Path();

    path.addRRect(
      _borderRadius.resolve(textDirection).toRRect(rect).deflate(_side.width),
    );

    return path;
  }

  @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    final Path path = Path();
    final RRect rrect = _borderRadius.resolve(textDirection).toRRect(rect);

    path.moveTo(0, 10);
    path.quadraticBezierTo(0, 0, 10, 0);
    path.lineTo(rrect.width - 30, 0);
    path.lineTo(rrect.width - 20, -10);
    path.lineTo(rrect.width - 10, 0);
    path.quadraticBezierTo(rrect.width, 0, rrect.width, 10);
    path.lineTo(rrect.width, rrect.height - 10);
    path.quadraticBezierTo(
        rrect.width, rrect.height, rrect.width - 10, rrect.height);
    path.lineTo(10, rrect.height);
    path.quadraticBezierTo(0, rrect.height, 0, rrect.height - 10);

    return path;
  }

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

  @override
  ShapeBorder scale(double t) => RoundedRectangleBorder(
        side: _side.scale(t),
        borderRadius: _borderRadius * t,
      );
}

And then

PopupMenuButton(
  offset: Offset(0, 50),
  shape: const TooltipShape(),
  ...
)

Now I want to change the color of PopupMenuButton border with this such shape. I mean the color of the popup menu border that is shown on button tap. Could anyone say how to do?

Upvotes: 0

Views: 604

Answers (1)

Dung Ngo
Dung Ngo

Reputation: 1472

You can use the paint() function

@override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {
  Paint paint = new Paint()
    ..color = Colors.red
    ..style = PaintingStyle.stroke
    ..strokeWidth = 2;
  canvas.drawPath(getOuterPath(rect), paint);
}

You should also add path.close(); to the end of the outerPath before return path; else the left side won't get a border.

Upvotes: 0

Related Questions