Flutter 在拖动另一个小部件时更新小部件

问题描述 投票:0回答:1

我是 Flutter 新手,我正在尝试构建一个具有两个可拖动圆圈的应用程序,其中一条线从一个圆圈到另一个圆圈

我设法做到了这一点,但在拖动过程中,线条没有跟随圆圈,因为圆圈位置仅在拖动结束后才更新。

我想让我的线在拖动过程中跟随我的圆圈,但我不知道该怎么做。 类似这样的东西:

这是一个包含我的代码示例的 Github:flutter_drag_example

我尝试使用 onDragUpdate 在拖动过程中设置圆圈位置的状态,但这不起作用(可能是因为设置状态导致小部件重建 idk)

flutter draggable
1个回答
0
投票

我正在努力解决您的问题。 这是示例代码:

import 'package:flutter/material.dart';

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

class DraggableCirclesApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Draggable Circles',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DraggableCirclesScreen(),
    );
  }
}

class DraggableCirclesScreen extends StatefulWidget {
  @override
  _DraggableCirclesScreenState createState() => _DraggableCirclesScreenState();
}

class _DraggableCirclesScreenState extends State<DraggableCirclesScreen> {
  Offset circleOnePosition = Offset(50, 200);
  Offset circleTwoPosition = Offset(250, 200);
  double circleRadius = 50;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Draggable Circles'),
      ),
      body: Stack(
        children: [
          CustomPaint(
            size: Size(MediaQuery.of(context).size.width, MediaQuery.of(context).size.height),
            painter: ShapesPainter(circleOnePosition, circleTwoPosition, circleRadius),
          ),
          Positioned(
            left: circleOnePosition.dx - circleRadius,
            top: circleOnePosition.dy - circleRadius,
            child: Draggable(
              feedback: Container(
                width: circleRadius * 2,
                height: circleRadius * 2,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: Colors.blue.withOpacity(0.5),
                ),
              ),
              child: Container(
                width: circleRadius * 2,
                height: circleRadius * 2,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: Colors.blue,
                ),
              ),
              onDraggableCanceled: (_, __) {},
              onDragEnd: (details) {
                setState(() {
                  circleOnePosition = details.offset;
                });
              },
            ),
          ),
          Positioned(
            left: circleTwoPosition.dx - circleRadius,
            top: circleTwoPosition.dy - circleRadius,
            child: Draggable(
              feedback: Container(
                width: circleRadius * 2,
                height: circleRadius * 2,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: Colors.blue.withOpacity(0.5),
                ),
              ),
              child: Container(
                width: circleRadius * 2,
                height: circleRadius * 2,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: Colors.blue,
                ),
              ),
              onDraggableCanceled: (_, __) {},
              onDragEnd: (details) {
                setState(() {
                  circleTwoPosition = details.offset;
                });
              },
            ),
          ),
        ],
      ),
    );
  }
}

class ShapesPainter extends CustomPainter {
  final Offset circleOnePosition;
  final Offset circleTwoPosition;
  final double circleRadius;

  ShapesPainter(this.circleOnePosition, this.circleTwoPosition, this.circleRadius);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.0;

    canvas.drawLine(circleOnePosition, circleTwoPosition, paint);

    canvas.drawCircle(circleOnePosition, circleRadius, paint);
    canvas.drawCircle(circleTwoPosition, circleRadius, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.