I wrote a code to drag boxes with gesture detector in flutter and it worked. Then I refactored the code for easy reading and it worked too but it moves very slow. What's the problem and how can I solve it?
I tried printing values to the console and there's nothing wrong with it there.
I wrote a code to drag boxes with gesture detector in flutter and it worked. Then I refactored the code for easy reading and it worked too but it moves very slow. What's the problem and how can I solve it?
I tried printing values to the console and there's nothing wrong with it there.
I wrote a code to drag boxes with gesture detector in flutter and it worked. Then I refactored the code for easy reading and it worked too but it moves very slow. What's the problem and how can I solve it?
I tried printing values to the console and there's nothing wrong with it there.
// old code that works
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
//so i can pass the widget size downward
body: Window(
size: MediaQuery.of(context).size,
),
);
}
}
class Window extends StatefulWidget {
final Size size;
const Window({Key key,@required this.size}) : super(key: key);
@override
_WindowState createState() => _WindowState();
}
class _WindowState extends State<Window> {
//for reference later
final boxSize = Size.square(100);
Offset firstBoxPosition = Offset.zero;
Offset secondBoxPosition = Offset.zero;
Offset thirdBoxPosition = Offset.zero;
@override
void initState() {
super.initState();
//so it starts at the center of the window
firstBoxPosition = widget.size / 2 - boxSize / 2 as Offset;
secondBoxPosition = widget.size / 4 - boxSize / 4 as Offset;
thirdBoxPosition = widget.size / 1.25 - boxSize / 1 as Offset;
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned(
top: firstBoxPosition.dy,
left: firstBoxPosition.dx,
child: GestureDetector(
onPanUpdate: (DragUpdateDetails details){
setState(() {
//add the previous state of the position to the current state of the drag
final offset = details.delta + firstBoxPosition;
//so it doesn't go out of bounds
//The bound here is zero (the origin) and the size of the window
final x = offset.dx.clamp(0.0, widget.size.width - boxSize.width);
final y = offset.dy.clamp(0.0, widget.size.height - boxSize.height);
firstBoxPosition = Offset(x,y);
});
},
child: SizedBox.fromSize(
size: boxSize,
child: Material(color: Colors.green,),
),
),
),
Positioned(
top: secondBoxPosition.dy,
left: secondBoxPosition.dx,
child: GestureDetector(
onPanUpdate: (DragUpdateDetails details){
setState(() {
//add the previous state of the position to the current state of the drag
final offset = details.delta + secondBoxPosition;
//so it doesn't go out of bounds
//The bound here is zero (the origin) and the size of the window
final x = offset.dx.clamp(0.0, widget.size.width - boxSize.width);
final y = offset.dy.clamp(0.0, widget.size.height - boxSize.height);
secondBoxPosition = Offset(x,y);
});
},
child: SizedBox.fromSize(
size: boxSize,
child: Material(color: Colors.blue,),
),
),
),
Positioned(
top: thirdBoxPosition.dy,
left: thirdBoxPosition.dx,
child: GestureDetector(
onPanUpdate: (DragUpdateDetails details){
setState(() {
//add the previous state of the position to the current state of the drag
final offset = details.delta + thirdBoxPosition;
//so it doesn't go out of bounds
//The bound here is zero (the origin) and the size of the window
final x = offset.dx.clamp(0.0, widget.size.width - boxSize.width);
final y = offset.dy.clamp(0.0, widget.size.height - boxSize.height);
thirdBoxPosition = Offset(x,y);
});
},
child: SizedBox.fromSize(
size: boxSize,
child: Material(color: Colors.red,),
),
),
),
],
);
}
}
//refactored code that's moving slowly
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
//so i can pass the widget size downward
body: Window(
size: MediaQuery.of(context).size,
),
);
}
}
class Window extends StatefulWidget {
const Window({Key key, @required this.size}) : super(key: key);
final Size size;
@override
_WindowState createState() => _WindowState();
}
class _WindowState extends State<Window> {
//for reference later
final boxSize = Size.square(100);
Offset firstBoxPosition = Offset.zero;
Offset secondBoxPosition = Offset.zero;
Offset thirdBoxPosition = Offset.zero;
Rect get windowBounds => Offset.zero & widget.size;
@override
void initState() {
super.initState();
// This is not necessary but good for visualization
final boxCenter = boxSize / 2;
firstBoxPosition = widget.size / 2 - boxCenter as Offset;
secondBoxPosition = widget.size / 4 - boxCenter as Offset;
thirdBoxPosition = widget.size / 1.25 - boxCenter as Offset;
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
Box(
position: firstBoxPosition,
size: boxSize,
color: Colors.red,
bounds: windowBounds,
onDragged: (position) {
setState(() {
firstBoxPosition = position;
});
},
),
Box(
position: secondBoxPosition,
size: boxSize,
color: Colors.green,
bounds: windowBounds,
onDragged: (position) {
setState(() {
secondBoxPosition = position;
});
},
),
Box(
position: thirdBoxPosition,
size: boxSize,
color: Colors.blue,
bounds: windowBounds,
onDragged: (position) {
setState(() {
thirdBoxPosition = position;
});
},
),
],
);
}
}
class Box extends Positioned {
Box({
Key key,
@required Rect bounds,
@required Size size,
@required Offset position,
@required Color color,
@required ValueChanged<Offset> onDragged,
}) : super(
key: key,
top: position.dy,
left: position.dx,
width: size.width,
height: size.height,
child: GestureDetector(
onPanUpdate: (DragUpdateDetails details) {
//add the previous state of the position to the current state of the drag
final offset = details.delta + position;
//so it doesn't go out of bounds
final x = offset.dx.clamp(bounds.left, bounds.right - size.width);
final y = offset.dy.clamp(bounds.top, bounds.bottom - size.height);
onDragged.call(Offset(x, y));
},
child: Material(color: color),
),
);
}