如何在容器内拖动多个对象

3
我正在尝试在一个大容器内放置多个图像,并能够移动和旋转它们,如下图所示:

enter image description here

我一直在使用 CostumePainter 玩耍,这是我在遵循 this 指南时得出的结果。

enter image description here

有人知道如何使用多张图片来完成这个任务吗?
我的代码:
  dynamic _balls;

  double xPos = 100;
  double yPos = 100;

  bool isClick = false;

  @override
  Widget build(BuildContext context) {
    _balls = _paint(xPosition: xPos, yPosition: yPos, ballRad: 20);

    return Scaffold(
      appBar: AppBar(
        title: const Text("Drag and Drop"),
      ),
      body: Center(
        child: GestureDetector(
          onHorizontalDragDown: (details) {
            setState(() {
              if (_balls.isBallRegion(
                  details.localPosition.dx, details.localPosition.dy)) {
                isClick = true;
              }
            });
          },
          onHorizontalDragEnd: (details) {
            setState(() {
              isClick = false;
            });
          },
          onHorizontalDragUpdate: (details) {
            if (isClick) {
              setState(() {
                xPos = details.localPosition.dx;
                yPos = details.localPosition.dy;
              });
            }
          },
          child: Container(
            height: 300,
            width: 300,
            color: Colors.lightBlueAccent,
            child: CustomPaint(
              painter: _balls,
            ),
          ),
        ),
      ),
    );
  }
2个回答

3

我按照这篇指南做了,它帮助了我。顺便提一下,这是博客。

这是代码:

// @dart=2.9
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class ContainerList {
  double height;
  double width;
  double scale;
  double rotation;
  double xPosition;
  double yPosition;

  ContainerList({
    this.height,
    this.rotation,
    this.scale,
    this.width,
    this.xPosition,
    this.yPosition,
  });
}

class HomePage extends StatefulWidget {
  const HomePage({Key key}) : super(key: key);

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

class _HomePageState extends State<HomePage> {
  List<ContainerList> list = [];
  Offset _initPos;
  Offset _currentPos = Offset(0, 0);
  double _currentScale;
  double _currentRotation;
  Size screen;

  @override
  void initState() {
    screen = Size(400, 500);
    list.add(ContainerList(
      height: 200.0,
      width: 200.0,
      rotation: 0.0,
      scale: 1.0,
      xPosition: 0.1,
      yPosition: 0.1,
    ));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
        height: 500.0,
        color: Colors.blue.withOpacity(0.8),
        width: double.infinity,
        child: Stack(
          children: list.map((value) {
            return GestureDetector(
              onScaleStart: (details) {
                if (value == null) return;
                _initPos = details.focalPoint;
                _currentPos = Offset(value.xPosition, value.yPosition);
                _currentScale = value.scale;
                _currentRotation = value.rotation;
              },
              onScaleUpdate: (details) {
                if (value == null) return;
                final delta = details.focalPoint - _initPos;
                final left = (delta.dx / screen.width) + _currentPos.dx;
                final top = (delta.dy / screen.height) + _currentPos.dy;

                setState(() {
                  value.xPosition = Offset(left, top).dx;
                  value.yPosition = Offset(left, top).dy;
                  value.rotation = details.rotation + _currentRotation;
                  value.scale = details.scale * _currentScale;
                });
              },
              child: Stack(
                children: [
                  Positioned(
                    left: value.xPosition * screen.width,
                    top: value.yPosition * screen.height,
                    child: Transform.scale(
                      scale: value.scale,
                      child: Transform.rotate(
                        angle: value.rotation,
                        child: Container(
                          height: value.height,
                          width: value.width,
                          child: FittedBox(
                            fit: BoxFit.fill,
                            child: Listener(
                              onPointerDown: (details) {
                                // if (_inAction) return;
                                // _inAction = true;
                                // _activeItem = val;
                                _initPos = details.position;
                                _currentPos =
                                    Offset(value.xPosition, value.yPosition);
                                _currentScale = value.scale;
                                _currentRotation = value.rotation;
                              },
                              onPointerUp: (details) {
                                // _inAction = false;
                              },
                              child: Container(
                                height: value.height,
                                width: value.width,
                                color: Colors.red,
                              ),
                              // child: Image.network(value.name),
                            ),
                          ),
                        ),
                      ),
                    ),
                  )
                ],
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

2
作为一项学习练习,我创建了一个基本的Flutter应用程序,至少演示了拖动独立项目并进行选择、删除和重新排序等几个功能。旋转功能存在一些小问题。 https://github.com/SpiRaiL/emoji_party_2 enter image description here

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接