8

I have the following widget:

class OutsiderButton extends StatelessWidget {

  final Function onPressed;
  final Icon icon;
  final OutsiderButtonPosition position;

  OutsiderButton({this.onPressed, @required this.icon, this.position});

  @override
  Widget build(BuildContext context) {
    return new Stack(fit: StackFit.loose, alignment: Alignment.center, children: [
      new CustomPaint(
        painter: new _OutsiderShape(position: position),
        size: Size(60.0, 60.0),
        isComplex: false,
      ),
      OutlineButton(
        borderSide: BorderSide(width: 1.0, color: Colors.white),
        color: AppThemeColors.accentColor,
        shape: new CircleBorder(),
        child: new Padding(
          padding: const EdgeInsets.all(6.0),
          child: icon,
        ),
        onPressed: onPressed,
      )
    ]);
  }
}

It uses CustomPainter to draw the background. I need this CustomPainter to draw a shadow, but every time the widget is clicked, the shadow is redrawn and gets stronger and stronger. Here is the CustomPainter:

class _OutsiderShape extends CustomPainter {

  final Paint bookMarkPaint;
  final double hexagonOffset = 15.0;
  final OutsiderButtonPosition position;
  Path path = Path();

  _OutsiderShape({this.position = OutsiderButtonPosition.TOP}) : bookMarkPaint = new Paint() {
    bookMarkPaint.color = AppThemeColors.primaryColorLight;
    bookMarkPaint.style = PaintingStyle.fill;
  }

  @override
  void paint(Canvas canvas, Size size) {

    canvas.save();

    if (position == OutsiderButtonPosition.BOTTOM) {
      canvas.rotate(pi);
      canvas.translate(-size.width, -size.height);
    }

    path.moveTo(0.0, hexagonOffset);
    path.relativeLineTo(size.width / 3, -hexagonOffset);
    path.relativeLineTo(size.width / 3, 0.0);
    path.relativeLineTo(size.width / 3, hexagonOffset);
    path.relativeLineTo(0.0, size.height - hexagonOffset);
    path.relativeLineTo(-size.width, 0.0);
    path.close();

    canvas.drawShadow(path, Colors.grey[900], 2.0, false);
    canvas.drawPath(path, bookMarkPaint);

    canvas.restore();
  }

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

Here is how the shadow looks like after four clicks.

Wrong Shadow

How can I avoid this behavior?

Andre Haueisen
  • 468
  • 2
  • 8
  • 20

3 Answers3

10

The problem in this line

//problem here 
canvas.drawShadow(path, Colors.grey[900], 2.0, false)

//change the alpha color of your grey color like this 
canvas.drawShadow(path, Colors.grey.withAlpha(50), 4.0, false);
sourav pandit
  • 8,647
  • 2
  • 19
  • 17
2

My guess is that Flutter does not clear the canvas before the redraw, so you are drawing over the existing shadow.

You can try to clear the canvas manually at the beginning of your paint method:

canvas.drawColor(Color(0), BlendMode.clear);
boformer
  • 28,207
  • 10
  • 81
  • 66
  • I tried to run your code snippet, and I am unable to reproduce the problem. Are you running the latest version of flutter? To find out what the problem is, I would recommend you to post a complete code snippet. – boformer Jun 24 '18 at 19:25
1

You have canvas.save line in your code. That's why it gets saved.

Alexander Farkas
  • 529
  • 3
  • 11