-
-
Save sma/c6a9111d58c3deb83711106cec6152ee to your computer and use it in GitHub Desktop.
| // run in DartPad: <https://dartpad.dev/c6a9111d58c3deb83711106cec6152ee> | |
| import 'package:flutter/material.dart'; | |
| void main() { | |
| runApp(MaterialApp(home: RectsExample())); | |
| } | |
| class RectsExample extends StatefulWidget { | |
| @override | |
| _RectsExampleState createState() => _RectsExampleState(); | |
| } | |
| class _RectsExampleState extends State<RectsExample> { | |
| int _index = -1; | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| body: Center( | |
| child: Rects( | |
| rects: [ | |
| Rect.fromLTRB(10, 20, 30, 40), | |
| Rect.fromLTRB(40, 60, 80, 100), | |
| ], | |
| selectedIndex: _index, | |
| onSelected: (index) { | |
| setState(() { | |
| _index = index; | |
| }); | |
| }, | |
| ), | |
| ), | |
| ); | |
| } | |
| } | |
| class Rects extends StatelessWidget { | |
| final List<Rect> rects; | |
| final void Function(int) onSelected; | |
| final int selectedIndex; | |
| const Rects({ | |
| Key key, | |
| @required this.rects, | |
| @required this.onSelected, | |
| this.selectedIndex = -1, | |
| }) : super(key: key); | |
| @override | |
| Widget build(BuildContext context) { | |
| return GestureDetector( | |
| onTapDown: (details) { | |
| RenderBox box = context.findRenderObject(); | |
| final offset = box.globalToLocal(details.globalPosition); | |
| final index = rects.lastIndexWhere((rect) => rect.contains(offset)); | |
| if (index != -1) { | |
| onSelected(index); | |
| return; | |
| } | |
| onSelected(-1); | |
| }, | |
| child: CustomPaint( | |
| size: Size(320, 240), | |
| painter: _RectPainter(rects, selectedIndex), | |
| ), | |
| ); | |
| } | |
| } | |
| class _RectPainter extends CustomPainter { | |
| static Paint _red = Paint()..color = Colors.red; | |
| static Paint _blue = Paint()..color = Colors.blue; | |
| final List<Rect> rects; | |
| final int selectedIndex; | |
| _RectPainter(this.rects, this.selectedIndex); | |
| @override | |
| void paint(Canvas canvas, Size size) { | |
| var i = 0; | |
| for (Rect rect in rects) { | |
| canvas.drawRect(rect, i++ == selectedIndex ? _red : _blue); | |
| } | |
| } | |
| @override | |
| bool shouldRepaint(CustomPainter oldDelegate) { | |
| return true; | |
| } | |
| } |
this is my code below:-
import 'package:BLEMesh/draw_circle.dart';
import 'package:flutter/material.dart';
class DrawCircleExample extends StatefulWidget {
@OverRide
_DrawCircleExampleState createState() => _DrawCircleExampleState();
}
class _DrawCircleExampleState extends State {
int _index = -1;
@OverRide
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Circles(
circls: [
Circle(center: {"x": 100, "y": 400}, radius: 60),
Circle(center: {"x": 180, "y": 600}, radius: 28),
Circle(center: {"x": 150, "y": 180}, radius: 40),
Circle(center: {"x": 200, "y": 400}, radius: 35),
Circle(center: {"x": 80, "y": 190}, radius: 18),
Circle(center: {"x": 200, "y": 120}, radius: 20),
Circle(center: {"x": 300, "y": 240}, radius: 36),
],
selectedIndex: _index,
onSelected: (index) {
setState(() {
_index = index;
});
},
),
),
);
}
}
class Circles extends StatelessWidget {
final List circls;
final void Function(int) onSelected;
final int selectedIndex;
//final Map<String, double> center;
// final double radius;
const Circles(
{Key key,
@required this.circls,
@required this.onSelected,
this.selectedIndex = -1,
}): super(key: key);
@OverRide
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (details) {
RenderBox box = context.findRenderObject();
final offset = box.globalToLocal(details.globalPosition);
print(offset);
final index = circls.lastIndexWhere((element) => true);
if (index != -1) {
onSelected(index);
return;
}
onSelected(-1);
},
child: CustomPaint(
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height),
painter: DrawCircle(circls: circls, selectedIndex: selectedIndex),
),
);
}
}
class DrawCircle extends CustomPainter {
Map<String, double> center;
double radius;
final int selectedIndex;
static Paint _red = Paint()..color = Colors.red;
static Paint _blue = Paint()..color = Colors.blue;
final List circls;
DrawCircle({this.circls, this.selectedIndex});
@OverRide
void paint(Canvas canvas, Size size) {
var i = 0;
// Paint brush = new Paint()
// ..color = Colors.red
// ..strokeCap = StrokeCap.round
// ..style = PaintingStyle.fill
// ..strokeWidth = 30;
for (Circle circ in circls) {
canvas.drawCircle(
Offset(circ.center["x"], circ.center["y"]), circ.radius, i++ == selectedIndex ? _red : _blue);
}
}
@OverRide
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
please help me to make it tappable.how can I get the index of circle.
final index = circls.lastIndexWhere((element) => true);
@rudeboyas you don't seem to be doing any actual checks
To use circles instead of rectangles, you need to implement a different hit test (line 56) and of course a different way to display them (line 84). For example:
56: final index = rects.lastIndexWhere((rect) => (rect.center - offset).distance < rect.shortestSide / 2);
84: canvas.drawCircle(rect.center, rect.shortestSide / 2, i++ == selectedIndex ? _red : _blue);thanks got it.
Can we detect which geometry shape is draw on screen through custom painter ?
No, only with some kind of model that represents the geometric forms displayed by the painter.
@sma I need to do the same with a circle drawn with multiple arcs. I need to see which arc tapped by the user.
Please have a look at this. https://dartpad.dev/4f1dccf37910f61840d430a3947e4135. Please help me!
hello everyone I follow the same approach for circle. but I can't able to find the index of offset. please help me. this is my code below:-
import 'package:flutter/material.dart';
class CircleExample extends StatelessWidget {
@OverRide
Widget build(BuildContext context) {
return MaterialApp(
title: 'Painter',
home: Stack(
children: [
Circle(center: {"x": 100, "y": 400}, radius: 60, positioned: 0),
Circle(center: {"x": 180, "y": 600}, radius: 28),
Circle(center: {"x": 150, "y": 180}, radius: 40),
Circle(center: {"x": 200, "y": 400}, radius: 35),
Circle(center: {"x": 80, "y": 190}, radius: 18),
Circle(center: {"x": 200, "y": 120}, radius: 20),
Circle(center: {"x": 300, "y": 240}, radius: 36),
],
),
);
}
}
class Circle extends StatefulWidget {
final Map<String, double> center;
final double radius;
Circle({this.center, this.radius, int positioned});
@OverRide
_CircleState createState([Offset offset]) => _CircleState();
}
class _CircleState extends State with SingleTickerProviderStateMixin {
AnimationController _controller;
@OverRide
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
}
@OverRide
void dispose() {
super.dispose();
_controller.dispose();
}
@OverRide
Widget build(BuildContext context) {
return CustomPaint(
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height),
foregroundPainter:
DrawCircle(center: widget.center, radius: widget.radius),
);
}
}
class DrawCircle extends CustomPainter {
Map<String, double> center;
double radius;
DrawCircle({this.center, this.radius});
@OverRide
void paint(Canvas canvas, Size size) {
Paint brush = new Paint()
..color = Colors.red
..strokeCap = StrokeCap.round
..style = PaintingStyle.fill
..strokeWidth = 30;
canvas.drawCircle(Offset(center["x"], center["y"]), radius, brush);
}
@OverRide
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}