1

I'm trying to handle taps for three painted "quartercirlces" using the CustomPaint widget. I've tried adding GestureDetectors around the QuarterCirclePainter class. Even tried using using a GestureRecognizer for the TextSpan without any success. Tried wrapping it in containers wrapped in gestureDetectors. Looked at similar posts about adding GestureDetectors around the CustomPaint, but none of them seems to work in this case. How can this be achieved?

class CategoryCircle extends StatelessWidget {
  final Color color;
  final double startAngle;
  final String category;
  final Offset textOffset;
  CategoryCircle({this.color, this.startAngle, this.category, this.textOffset});

  Widget build(BuildContext context) {
    FocusScope.of(context).nextFocus();
    return FractionallySizedBox(
      widthFactor: 1,
      heightFactor: 1,
      child: Center(
        child: CustomPaint(
            painter: QuarterCirclePainter(
                context: context,
                color: color,
                startAngle: startAngle,
                sweepAngle: math.pi * 2 / 3,
                text: category,
                textOffset: textOffset)),
      ),
    );
  }
}

class QuarterCirclePainter extends CustomPainter {
  final BuildContext context;
  final Color color;
  final double startAngle;
  final double sweepAngle;
  final String text;
  final Offset textOffset;

  const QuarterCirclePainter(
      {this.context,
      this.color,
      this.startAngle,
      this.sweepAngle,
      this.text,
      this.textOffset});

  @override
  void paint(Canvas canvas, Size size) {
    Offset center = Offset(size.width / 2, size.height / 2);
    Rect rect = Rect.fromCircle(center: center, radius: 130);
    Path path = Path()
      // set the "current point"
      ..moveTo(center.dx, center.dy)
      ..arcTo(rect, startAngle, (math.pi * 2) / 3, false);
    canvas.drawPath(path, Paint()..color = color);
    TextSpan span = new TextSpan(
        style: GoogleFonts.overpass(
            textStyle: TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
        text: text);
    TextPainter tp = new TextPainter(
        text: span,
        textAlign: TextAlign.center,
        textDirection: TextDirection.ltr);
    tp.layout();
    tp.paint(canvas, textOffset);
  }

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

enter image description here

Leobd
  • 29
  • 6

1 Answers1

1

I made a CustomClipper with what you did in the QuarterCirclePainter, it looks like this:

class QuaterCircleClipper extends CustomClipper<Path>{
  double startAngle, sweepAngle;

  QuaterCircleClipper({@required this.startAngle, @required this.sweepAngle});


  @override
  Path getClip(Size size){
    Offset center = Offset(size.width / 2, size.height / 2);
    Rect rect = Rect.fromCircle(center: center, radius: 130);
    Path path = Path()
      // set the "current point"
      ..moveTo(center.dx, center.dy)
      ..arcTo(rect, startAngle, (math.pi * 2) / 3, false);
      return path;
  }

  @override
  bool shouldReclip(oldCliper) => false;
}

And used a ClipPath with the above CustomClipper as clipper to wrap a GestureDetector which has a blue Container as its child

Container(
  width: MediaQuery.of(context).size.width,
  height: MediaQuery.of(context).size.height,
  child: AspectRatio(
    aspectRatio: 1,
    child: ClipPath(
      clipper: QuaterCircleClipper(startAngle: 0, sweepAngle: 120),
      child: GestureDetector(
        onTap: (){showDialog(context: context, builder: (_) => AlertDialog(content: Text("Tap Detected"),));},
        child: Container(
          color: Colors.blueAccent,
        )
      ),
    ),
  )
),

enter image description here

Kennith
  • 323
  • 3
  • 10
  • Seems to be working thanks! But how would you add the text that I have for the different categories on top of the Quartercricles? @Kennith – Leobd Aug 26 '20 at 20:04
  • I think it depends on whether the layout changes over time. If the angles won't change then I would just hardcode the text position with `Stack` and `Align`, otherwise you will need some calculations. @Leobd – Kennith Aug 26 '20 at 21:22