As the above picture shows i have 4 seprate areas with 4 seperate motion defined. For example: I want to slide the positioned widget in top left to bottom right diagonal if user begins sliding at the red box. I am able to move and slide the widget the side that i want to slide but the animation of sliding is not smooth.I think that issue happens because of the wrong X and Y values to change position. So here is the code.
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'dart:math' as math;
class HomePage extends StatefulWidget {
HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
double? dragStartY;
double? dragStartX;
bool dragging = false;
double? top;
double? bottom;
double? left;
double? right;
int? lastAction;
double angle = 0;
void actionDecider(double currentX, double currentY, double changeY,
double changeX, int triggerType) {
//0 DISMISS
//1 LIKE
//2 IMAGE -> 21 FORWARD - 22 BACK
//3 SUPER LIKE
//4 DIRECT MESSAGE
//TRIGGER TYPE -> 0 VERTICAL - 1 HORIZONTAL
if ((dragStartX! >= 0 && dragStartX! <= 150) &&
(dragStartY! >= 0 && dragStartY! <= 75)) {
if ((triggerType == 0) && (currentY > dragStartY! || changeY == 0)) {
print(right);
setState(() {
lastAction = 0;
right = right! - changeY;
angle = angle math.pi / 600;
bottom = bottom! - changeY;
left = null;
});
} else if ((triggerType == 1) &&
(currentX > dragStartX! || changeX == 0)) {
print(right);
setState(() {
lastAction = 0;
right = right! - changeX;
angle = angle math.pi / 600;
bottom = bottom! - changeX;
left = null;
});
}
} else if ((dragStartX! > 150 && dragStartX! <= 300) &&
(dragStartY! >= 0 && dragStartY! <= 75)) {
if ((triggerType == 0) && (currentY > dragStartY! || changeY == 0)) {
print("left");
print(left);
print("cx");
print(changeX);
setState(() {
lastAction = 1;
angle = angle - math.pi / 600;
right = null;
left = -changeX;
});
} else if ((triggerType == 1) &&
(currentX < dragStartX! || changeX == 0)) {
print("left");
print(left);
print("cx");
print(changeX);
setState(() {
lastAction = 1;
angle = angle - math.pi / 600;
right = null;
left = -changeX;
});
}
} else if ((dragStartX! >= 0 && dragStartX! <= 300) &&
(dragStartY! > 75 && dragStartY! < 225)) {
if (currentX > dragStartX! || changeX == 0) {
setState(() {
lastAction = 21;
});
} else if (currentX < dragStartX! || changeX == 0) {
setState(() {
lastAction = 22;
});
}
} else if ((dragStartX! >= 0 && dragStartX! <= 300) &&
(dragStartY! > 225 && dragStartY! <= 300)) {
if (dragStartY! > currentY || changeY == 0) {
setState(() {
lastAction = 3;
});
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: double.maxFinite,
height: double.maxFinite,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 300,
height: 300,
child: Stack(
clipBehavior: Clip.none,
children: [
Positioned(
child: Container(
width: 300,
height: 300,
color: Colors.blue,
)),
Positioned(
right: dragging ? right : 0,
bottom: dragging ? bottom : 0,
child: Transform.rotate(
angle: angle,
child: GestureDetector(
onVerticalDragStart: (details) {
setState(() {
dragging = true;
dragStartX = details.localPosition.dx;
dragStartY = details.localPosition.dy;
});
},
onHorizontalDragStart: (details) {
setState(() {
dragging = true;
dragStartX = details.localPosition.dx;
dragStartY = details.localPosition.dy;
});
},
onVerticalDragUpdate: (details) {
actionDecider(
details.localPosition.dx,
details.localPosition.dy,
details.delta.dy,
details.delta.dx,
0);
},
onHorizontalDragUpdate: (details) {
actionDecider(
details.localPosition.dx,
details.localPosition.dy,
details.delta.dy,
details.delta.dx,
1);
},
onHorizontalDragEnd: (details) {
setState(() {
dragging = false;
dragStartX = null;
dragStartY = null;
angle = 0.0;
right = 0;
bottom = 0;
});
},
onVerticalDragEnd: (details) {
setState(() {
dragging = false;
dragStartX = null;
dragStartY = null;
angle = 0.0;
right = 0;
bottom = 0;
});
},
child: Container(
width: 300,
height: 300,
child: Stack(
children: [
Positioned(
left: 0,
top: 0,
child: Container(
width: 150,
height: 75,
color: Colors.red,
)),
Positioned(
right: 0,
top: 0,
child: Container(
width: 150,
height: 75,
color: Colors.black,
)),
Positioned(
right: 0,
left: 0,
top: 75,
child: Container(
width: 300,
height: 150,
color: Colors.purple,
)),
Positioned(
left: 0,
bottom: 0,
child: Container(
width: 300,
height: 75,
color: Colors.green,
)),
],
),
)),
)),
],
),
)
],
),
),
);
}
}
What should i do for slide these positioned widgets smoothly on dragUpdate events?
CodePudding user response:
The problem is that you don't use any animation in your code. You just change states.
Try to wrap your Stack
in AnimatedBuilder
or to use AnimatedPositioned
instead of Positioned
.
Also you can use InteractiveViewer
(wrap your Stack
in it), which lets you to interact with its child by dragging.
CodePudding user response:
The parent widget in this flutter app is Padding which is employing its only property padding to print an empty space of 300 px on the top of its child widget which is Stack. The alignment is set to center in the Stack widget. Stack, as it does, is taking a list of widgets as children, here it’s taking in two Positioned widgets. The first one is containing a green-colored material design message icon, which is 128 px long in width and height.