Created
June 13, 2020 07:11
-
-
Save Barttje/3d51c65d59a0b3cd9d9a28d88b965839 to your computer and use it in GitHub Desktop.
Reacting to clicks on circles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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