简体   繁体   English

Flutter:在一堆小部件中结合 Draggable 和 GestureDetector

[英]Flutter: combining Draggable and GestureDetector in a Stack of widgets

I'm trying to have a stack of Container widgets that are able to be dragged around and dropped in place, but also moved to the top of the stack if tapped.我正在尝试拥有一堆 Container 小部件,这些小部件可以被拖动并放置在适当的位置,但如果被点击,也可以移动到堆栈的顶部。 At the moment, I can only get one or the other to work.目前,我只能让其中一个工作。

The code below allows dragging and dropping, but the moveToTop function in each GestureDetector doesn't seem to work.下面的代码允许拖放,但每个 GestureDetector 中的moveToTop function 似乎不起作用。 drag.gif拖动.gif

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StackOfContainers(),
    );
  }
}
class StackOfContainers extends StatefulWidget {
  @override
  _StackOfContainersState createState() => _StackOfContainersState();
}

class _StackOfContainersState extends State<StackOfContainers> {
  List<Offset> draggablePositions = [Offset(0, 0), Offset(30, 30), Offset(60, 60)];

  List<GlobalKey> draggableKeys = [GlobalKey(), GlobalKey(), GlobalKey()];

  List<Widget> stackOfContainers = [];

  void moveToTop(Key key) {
    setState(() {
      for (var i = 0; i < stackOfContainers.length; i++) {
        Widget container = stackOfContainers[i];
        if (key == container.key) {
          stackOfContainers.remove(container);
          stackOfContainers.add(container);
        }
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    stackOfContainers = [
      Positioned(
        key: draggableKeys[0],
        top: draggablePositions[0].dy,
        left: draggablePositions[0].dx,
        child: GestureDetector(
          onTap: () {
            setState(() {
              moveToTop(draggableKeys[0]);
            });
          },
          child: Draggable(
            onDraggableCanceled: (velocity, offset) {
              setState(() {
                draggablePositions[0] = offset;
              });
            },
            child: Container(
              color: Colors.lightBlueAccent,
              height: 100,
              width: 100,
            ),
            feedback: Container(
              color: Colors.lightBlueAccent,
              height: 100,
              width: 100,
            ),
            childWhenDragging: Container(),
          ),
        ),
      ),
      Positioned(...),
      Positioned(...)
    ];

    return SafeArea(
      child: Scaffold(
        backgroundColor: Colors.black,
        body: Stack(
          children: stackOfContainers,
        ),
      ),
    );
  }


}

(The two Positioned(...) widgets above are similar pink and yellow containers.) (上面的两个Positioned(...)小部件是类似的粉色和黄色容器。)

If I move stackOfContainers inside initState() , then moveToTop works in each GestureDetector but each container returns to the starting point after dragging.如果我在initState()中移动stackOfContainers ,则moveToTop在每个 GestureDetector 中工作,但每个容器在拖动后返回到起点。

tap.gif点击.gif

...

class _StackOfContainersState extends State<StackOfContainers> {
  @override
  void initState() {
    super.initState();
    stackOfContainers=[
      Positioned(...),
      Positioned(...),
      Positioned(...)
    ];
 }

...

Is there a way to combine these functionalities?有没有办法结合这些功能?

I'm not sure but I think you are just dragging,not tapping.So onTap will not work.我不确定,但我认为你只是在拖动,而不是点击。所以 onTap 不起作用。

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

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