简体   繁体   English

Flutter 定位小部件平滑滑动

[英]Flutter positioned widget smooth slide

在此处输入图像描述

As the above picture shows i have 4 seprate areas with 4 seperate motion defined.如上图所示,我有 4 个单独的区域,定义了 4 个单独的运动。 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.我可以将小部件移动并滑动到我想要滑动的一侧,但滑动动画不流畅。我认为这个问题的发生是因为错误的 X 和 Y 值改变了位置。 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?我应该怎么做才能在 dragUpdate 事件中平滑地滑动这些定位的小部件?

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 .尝试将Stack包装在AnimatedBuilder中或使用AnimatedPositioned而不是Positioned

Also you can use InteractiveViewer (wrap your Stack in it), which lets you to interact with its child by dragging.您还可以使用InteractiveViewer (将您的Stack包裹在其中),它可以让您通过拖动与其子项进行交互。

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.这个 Flutter 应用程序中的父小部件是 Padding,它使用其唯一的属性 padding 在其子小部件 Stack 的顶部打印 300 像素的空白空间。 The alignment is set to center in the Stack widget.对齐方式设置为在 Stack 小部件中居中。 Stack, as it does, is taking a list of widgets as children, here it's taking in two Positioned widgets. Stack,就像它所做的那样,将一个小部件列表作为孩子,这里它接受两个定位的小部件。 The first one is containing a green-colored material design message icon, which is 128 px long in width and height.第一个包含一个绿色的 Material Design 消息图标,其宽度和高度均为 128 像素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM