如何在Flutter中动态绘制从A点到B点的直线?

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

所以我有一个自定义地图 4x3 这就是我想要做的:当我点击两个不同的方块时,它会显示从方块 1 到方块 2 的一条线(如折线)。

我还没有找到实现这一目标的解决方案

请帮助我。您对如何实现这一目标有什么建议吗? 有没有推荐的库来完成这个任务?

这是我使用custompaint手工定制的代码:

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          Center(
            child: Image.asset(
              'assets/Sơ đồ mô phỏng.png',
              height: 300,
            ),
          ),
          CustomPaint(
            painter: MyPainter(),
          ),
          Positioned(
            top: 50,
            left: 10,
            child: IconButton(
              onPressed: () {},
              icon: const Icon(
                Icons.map,
                size: 35,
              ),
            ),
          ),
          Positioned(
            top: 100,
            left: 10,
            child: IconButton(
              onPressed: () {},
              icon: const Icon(
                Icons.pattern_sharp,
                size: 35,
              ),
            ),
          ),
          Positioned(
            top: 150,
            left: 10,
            child: IconButton(
              onPressed: () {},
              icon: const Icon(
                Icons.location_on,
                size: 35,
              ),
            ),
          )
        ],
      ),
    );
  }
}

class MyPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    const p1 = Offset(165, 100);
    const p2 = Offset(165, 135);
    final paint1 = Paint()
      ..color = Colors.black
      ..strokeJoin
      ..strokeWidth = 3;
    const p3 = Offset(165, 135);
    const p4 = Offset(490, 135);
    final paint2 = Paint()
      ..color = Colors.black
      ..strokeWidth = 3;
    const p5 = Offset(490, 100);
    const p6 = Offset(490, 135);
    final paint3 = Paint()
      ..color = Colors.black
      ..strokeWidth = 3;
    canvas.drawLine(p1, p2, paint1);
    canvas.drawLine(p3, p4, paint2);
    canvas.drawLine(p5, p6, paint3);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}
flutter dart maps cross-platform polyline
1个回答
1
投票

我解决了 这是解决方案

class TestDraw2Point extends StatefulWidget {
  @override
  _TestDraw2PointState createState() => _TestDraw2PointState();
}

class _TestDraw2PointState extends State<TestDraw2Point> {
  List<Offset> _points = [];

  void _addPoint(Offset point) {
    setState(() {
      _points.add(point);
      if (_points.length == 2) {
        _points = List.from(_points);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Draw Line Example'),
      ),
      body: GestureDetector(
        onTapDown: (TapDownDetails details) {
          _addPoint(details.localPosition);
        },
        child: CustomPaint(
          painter: LinePainter(points: _points),
          child: Container(),
        ),
      ),
    );
  }
}

class LinePainter extends CustomPainter {
  List<Offset> points;

  LinePainter({required this.points});

  @override
  void paint(Canvas canvas, Size size) {
    if (points.length == 2) {
      final paint = Paint()
        ..color = Colors.black
        ..strokeWidth = 3.0;

      canvas.drawLine(points[0], points[1], paint);
    }
  }

  @override
  bool shouldRepaint(LinePainter oldDelegate) => true;
}

这是绘制多线的另一个版本


class DrawLineScreen extends StatefulWidget {
  const DrawLineScreen({super.key});

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

class _DrawLineScreenState extends State<DrawLineScreen> {
  final List<Offset> _points = [];
  final List<List<Offset>> _lines = [];

  void _addPoint(Offset point) {
    setState(() {
      _points.add(point);
      if (_points.length == 2) {
        _lines.add(List.from(_points));
        _points.clear();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Draw Line Example'),
      ),
      body: GestureDetector(
        onTapDown: (TapDownDetails details) {
          _addPoint(details.localPosition);
        },
        child: CustomPaint(
          painter: LinePainter(lines: _lines, currentPoints: _points),
          child: Container(),
        ),
      ),
    );
  }
}

class LinePainter extends CustomPainter {
  List<List<Offset>> lines;
  List<Offset> currentPoints;

  LinePainter({required this.lines, required this.currentPoints});

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.black
      ..strokeWidth = 3.0;

    for (final line in lines) {
      canvas.drawLine(line[0], line[1], paint);
    }

    if (currentPoints.length == 2) {
      canvas.drawLine(currentPoints[0], currentPoints[1], paint);
    }
  }

  @override
  bool shouldRepaint(LinePainter oldDelegate) => true;
}
© www.soinside.com 2019 - 2024. All rights reserved.