Issue
I try many codes, this is last:
It should allow moving both widgets but nothing happens.
No output in console.
No error messages.
I tried on Android and Windows.
It seems that the events are not received by the widgets.
It seemed to me that HitTestBehavior.opaque was used for that.
I also tried with a Positioned.
import 'dart:math' as math;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class RadarPoint {
Offset position;
int stateValue;
double orientation;
RadarPoint({
required this.position,
required this.stateValue,
required this.orientation,
});
}
final List<RadarPoint> points = [
RadarPoint(position: const Offset(300, 60), orientation: 0, stateValue: 0),
RadarPoint(position: const Offset(300, 220), orientation: 45, stateValue: 1),
];
const double maxAngle = 150;
const double diameter = 200;
const List<Color> distanceColors = [
Colors.red,
Colors.orange,
Colors.yellow,
Colors.green,
];
class RadarPainter extends CustomPainter {
RadarPoint point;
double diameter;
List<Color> distanceColors;
double maxAngle;
RadarPainter({
required this.point,
required this.diameter,
required this.distanceColors,
required this.maxAngle,
});
double degreesToRads(double deg) => deg * math.pi / 180.0;
double currentDiameter(int i) => diameter / distanceColors.length * (i + 1);
@override
void paint(Canvas canvas, Size size) {
for (var i = distanceColors.length - 1; i > -1; i--) {
if (i >= point.stateValue) {
canvas.drawArc(
Rect.fromCenter(
center: point.position,
height: currentDiameter(i),
width: currentDiameter(i),
),
degreesToRads(point.orientation),
degreesToRads(maxAngle),
true,
Paint()..color = distanceColors[i],
);
}
}
canvas.drawCircle(point.position, 5, Paint()..color = Colors.black);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
class RadarWidget extends StatefulWidget {
final RadarPoint point;
const RadarWidget({super.key, required this.point});
@override
State<RadarWidget> createState() => _RadarWidgetState();
}
class _RadarWidgetState extends State<RadarWidget> {
late RadarPoint point;
@override
void initState() {
super.initState();
point = widget.point;
}
Widget _feedback() {
print('_feedback');
return CustomPaint(
painter: RadarPainter(
point: point,
diameter: diameter * 2,
distanceColors: distanceColors,
maxAngle: maxAngle,
),
);
}
@override
Widget build(BuildContext context) {
return Draggable<RadarPoint>(
data: point,
feedback: _feedback(),
onDragStarted: () {
print('onDragStarted');
},
onDragUpdate: (details) {
print('onDragUpdate');
},
onDragEnd: (details) {
print('onDragEnd');
},
onDraggableCanceled: (velocity, offset) {
print('onDraggableCanceled');
},
hitTestBehavior: HitTestBehavior.opaque,
child: CustomPaint(
painter: RadarPainter(
point: point,
diameter: diameter,
distanceColors: distanceColors,
maxAngle: maxAngle,
),
),
);
}
}
class App extends StatelessWidget {
App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Stack(
children: [
RadarWidget(point: points[0]),
RadarWidget(point: points[1]),
],
),
),
);
}
}
Future<void> main() async {
debugPrintGestureArenaDiagnostics = false;
runApp(App());
}
Solution
First issue is the RadarWidget
‘s CustomPaint
doesnt have fixed size which is covering the full body. You can provide the size on
child: CustomPaint(
size: Size(diameter * 2, diameter * 2),
painter: RadarPainter(
Next you may wrap Align/Positioned to Stack children. You can also check CustomMultiChildLayout. Also I might just prefer using GestureDetector( Stack([ Positioned(RadarItems)..) )]).
Answered By – Md. Yeasin Sheikh
Answer Checked By – Robin (FlutterFixes Admin)