Skip to content

Instantly share code, notes, and snippets.

@Barttje
Created June 13, 2020 07:11
Show Gist options
  • Save Barttje/3d51c65d59a0b3cd9d9a28d88b965839 to your computer and use it in GitHub Desktop.
Save Barttje/3d51c65d59a0b3cd9d9a28d88b965839 to your computer and use it in GitHub Desktop.
Reacting to clicks on circles
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(HexagonGridDemo());
class HexagonGridDemo extends StatelessWidget {
final GlobalKey blueCirclePainter = new GlobalKey();
final GlobalKey<_CircleState> blueCircle = new GlobalKey<_CircleState>();
final GlobalKey redCirclePainter = new GlobalKey();
final GlobalKey<_CircleState> redCircle = new GlobalKey<_CircleState>();
final GlobalKey yellowCirclePainter = new GlobalKey();
final GlobalKey<_CircleState> yellowCircle = new GlobalKey<_CircleState>();
final result = BoxHitTestResult();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Hexagon Grid Demo'),
),
body: Listener(
onPointerDown: (PointerEvent details) {
handleClick(details);
},
child: Stack(
children: <Widget>[
Circle(
model: CircleModel(
Offset(90, 120),
70,
Colors.blue,
blueCirclePainter,
),
key: blueCircle),
Circle(
model: CircleModel(
Offset(60, 60),
50,
Colors.red,
redCirclePainter,
),
key: redCircle),
Circle(
model: CircleModel(
Offset(140, 70),
40,
Colors.yellow,
yellowCirclePainter,
),
key: yellowCircle),
],
),
),
),
);
}
handleClick(PointerEvent details) {
if (isClicked(details, redCirclePainter)) {
redCircle.currentState.increaseSize();
}
if (isClicked(details, blueCirclePainter)) {
blueCircle.currentState.increaseSize();
}
if (isClicked(details, yellowCirclePainter)) {
yellowCircle.currentState.increaseSize();
}
}
bool isClicked(final PointerEvent details, final GlobalKey key) {
final RenderBox circleBox = key.currentContext.findRenderObject();
Offset localClick = circleBox.globalToLocal(details.position);
if (circleBox.hitTest(result, position: localClick)) {
return true;
}
return false;
}
}
class CircleModel {
CircleModel(this.center, this.radius, this.color, this.key);
final Offset center;
double radius;
final Color color;
final GlobalKey key;
}
class Circle extends StatefulWidget {
Circle({this.model, this.key});
final CircleModel model;
final GlobalKey<_CircleState> key;
@override
_CircleState createState() => _CircleState();
}
class _CircleState extends State<Circle> {
void increaseSize() {
setState(() {
widget.model.radius = widget.model.radius + 2;
});
}
@override
Widget build(BuildContext context) {
return CustomPaint(
key: widget.model.key,
painter: CirclePainter(
widget.model.center, widget.model.radius, widget.model.color),
child: Container(),
);
}
}
class CirclePainter extends CustomPainter {
final double radius;
final Offset center;
final Color color;
CirclePainter(this.center, this.radius, this.color);
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()..color = color;
canvas.drawCircle(center, radius, paint);
}
@override
bool shouldRepaint(CirclePainter oldDelegate) => oldDelegate.radius != radius;
@override
bool hitTest(Offset position) {
final Path path = new Path();
path.addRect(Rect.fromCircle(center: center, radius: radius));
return path.contains(position);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment