skip to Main Content

enter image description here

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?

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search