Можете ли вы программно поместить Draggable внутрь DragTarget?

Это звучит странно, чтобы спросить! Но у меня есть две цели перетаскивания и две перетаскиваемые. Я хочу, чтобы они начали по одному в каждой цели. Затем, когда один объект перетаскивается на вторую цель, перетаскиваемый объект второй цели должен перепрыгнуть на первую цель.

Я предполагаю, что проблема решается тем, можете ли вы программно поместить перетаскиваемый объект внутрь цели. Возможно ли это, или DragTarget не подходит?

Некоторый пример кода - я не могу запустить draggables внутри dragtargets

      import 'package:flutter/material.dart';

MyDraggable drag1 = new MyDraggable(Colors.red);
MyDraggable drag2 = new MyDraggable(Colors.green);
MyDragTarget target1 = new MyDragTarget();
MyDragTarget target2 = new MyDragTarget();

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(fontFamily: 'PressStart'),
      home: MyHomeScreen(),
    );
  }
}

class MyHomeScreen extends StatefulWidget {
  MyHomeScreen({Key key}) : super(key: key);
  createState() => MyHomeScreenState();
}

class MyHomeScreenState extends State<MyHomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.red[100],
      appBar: AppBar(
        toolbarHeight: 70.0,
        title: Center(child: Text('Swap the draggables')),
        backgroundColor: Colors.pink,
      ),
      body: Container(
        color: Colors.yellow[200],
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Center(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [target1, drag1, drag2, target2],
                // children: [target1, SizedBox(width: 100), target2],
              ),
            ),
            Text('Q1: Can the Draggables be started in the DragTargets?'),
            Text('Q2: If you drag from one target to the other, '
                'can the second swap to the other target?'),
          ],
        ),
      ),
    );
  } // End build()
} // End class MyHomeScreenState

class MyDragTarget extends StatelessWidget {
  bool dragAccepted = false;
  Color acceptedColor;
  @override
  Widget build(BuildContext context) {
    return Stack(children: [
      Container(color: Colors.blue,height: 90.0,width: 90.0,
        child: Padding(
          padding: const EdgeInsets.all(20.0),
          child: DragTarget<Color>(
            builder: (context, List<Color> acceptedData, rejectedData) {
              if (dragAccepted) {
                return MyDraggable(acceptedColor);
              } else {
                return Container(color: Colors.grey,height: 50,width: 50,);
              }
            },
            onWillAccept: (aColor) {
              acceptedColor = aColor;
              return true;
            },
            onMove: (moveData) {},
            onAccept: (aColor) { dragAccepted = true; },
            onLeave: (data) {},
          ),
        ),
      ),
    ]);
  } // Build
} // End Class MyDragTarget

class MyDraggable extends StatefulWidget {
  MyDraggable(this.color);
  final Color color;

  @override
  _MyDraggableState createState() => _MyDraggableState();
}

class _MyDraggableState extends State<MyDraggable> {
  @override
  Widget build(BuildContext context) {
    return Draggable(
      data: widget.color,
      child: Container(color: widget.color, height: 50, width: 50),
      feedback: Container(color: widget.color, height: 50, width: 50),
      childWhenDragging:
          Container(color: Colors.pink[100], height: 50, width: 50),
      onDragStarted: () {},
      onDragEnd: (dragDetails) {
        setState(() {});
      },
      onDragCompleted: () {},
      onDraggableCanceled: (velocity, offset) {},
    );
  }
}

1 ответ

Для Draggable по умолчанию из Flutter SDK не предусмотрен метод, который позволял бы нам изменять смещение/положение отображения в пользовательском интерфейсе (вся эта информация хранится в DraggableDetails файла ).

С учетом сказанного, есть 2 варианта, которые вы можете попробовать:

  • Создайте собственный класс, который позволяет программно управлять своей позицией в пользовательском интерфейсе.
  • Изменить имущество детей Draggableвиджет на основе onWillAcceptобратный вызов DragTargetкласс (т. colorкаждого контейнера в этом случае)
Другие вопросы по тегам