首页 > 解决方案 > 是否可以在 Flutter 的自定义容器中添加 Draggable 和 DragTarget 小部件?

问题描述

这是使用 ClipPath 获取字母“A”的自定义三个容器的代码。此代码也可以在这三个容器内绘制。但绘图可以在任何方向进行。我想让这段代码在第一个容器内从上到下绘制,当第一个绘制完成时,第二个容器被激活,在绘制第二个容器之后,第三个被激活(跟踪字母)。我认为应该有 3 对 Draggable 和 DragTarget。绘图是使用 GestureDetector 完成的。有没有办法使用 Draggable 小部件画线,请回复任何知道解决方案的人

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;

import 'package:flutter/services.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setEnabledSystemUIOverlays ([]);
  SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeRight,DeviceOrientation.landscapeLeft]).then((_){
    runApp(MyApp());
  });
}

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

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<Offset> points1 = [];
  List<Offset> points2 = [];
  List<Offset> points3 = [];

  

  @override
  Widget build(BuildContext context) {
    final double width  = MediaQuery.of(context).size.width;
    final double height  = MediaQuery.of(context).size.height;
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          points1.clear();
          points2.clear();
          points3.clear();
        },
      ),
      backgroundColor: Colors.teal,
      body: SafeArea(
        child:Center(
          child: Stack(
            children: [
              Positioned(
                left: MediaQuery.of(context).size.width*0.381,
                top:MediaQuery.of(context).size.height*0.560,
                child: ClipPath(
                  clipper: CPath3(),
                  child: Container(
                    height: height*0.07,
                    width: width*0.18,
                    child: GestureDetector(
                      onPanStart: (details){
                        this.setState(() {
                          points3.add(details.localPosition);
                        });
                      },
                      onPanUpdate: (details){
                        this.setState(() {
                          points3.add(details.localPosition);
                        });
                      },
                      onPanEnd: (details){
                        this.setState(() {
                          points3.add(null);
                        });
                      },
                      child: CustomPaint(
                        painter: MyPainter3(points3: points3),
                      ),
                    ),
                  ),
                ),
              ),//THIRD PATH
              Positioned(
                left: MediaQuery.of(context).size.width*0.283,
                // bottom: 0,
                top: MediaQuery.of(context).size.height*0.194,
                //right: 0,
                child: ClipPath(
                  clipper: CPath1(),
                  child: Container(
                    height: height*0.60,
                    width: width*0.20,
                    child: GestureDetector(
                      onPanStart: (details){
                        this.setState(() {
                          points1.add(details.localPosition);
                        });
                      },
                      onPanUpdate: (details){
                        this.setState(() {
                          points1.add(details.localPosition);
                        });
                      },
                      onPanEnd: (details){
                        this.setState(() {
                          points1.add(null);
                        });
                      },
                      child: CustomPaint(
                        painter: MyPainter1(points1: points1),
                      ),
                    ),
                  ),
                ),
              ),//FIRST PATH
              Positioned(
                left:  MediaQuery.of(context).size.width*0.467,
                // bottom: 0,
                top: MediaQuery.of(context).size.height*0.194,
                //right: 0,
                child: ClipPath(
                  clipper: CPath2(),
                  child: Container(
                    height: height*0.60,
                    width: width*0.20,
                    child: GestureDetector(
                      onPanStart: (details){
                        this.setState(() {
                          points2.add(details.localPosition);
                        });
                      },
                      onPanUpdate: (details){
                        this.setState(() {
                          points2.add(details.localPosition);
                        });
                      },
                      onPanEnd: (details){
                        this.setState(() {
                          points2.add(null);
                        });
                      },
                      child: CustomPaint(
                        painter: MyPainter2(points2: points2),
                      ),
                    ),
                  ),
                ),
              ),//SECOND PATH
            ],
          ),
        ),
      ),
    );
  }
}

class CPath1 extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path_0 = Path();
    path_0.moveTo(0,size.height);
    path_0.lineTo(size.width*0.2983628,size.height);
    path_0.lineTo(size.width,0);
    path_0.lineTo(size.width*0.7591676,0);
    path_0.lineTo(0,size.height);
    path_0.close();
    return path_0;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    // TODO: implement shouldReclip
    return true;
  }

}
class MyPainter1 extends CustomPainter {
  List<Offset> points1;
  MyPainter1({this.points1});
  @override
  void paint(Canvas canvas, Size size) {
   Paint background = Paint()..color =  Colors.white;
   Rect rect = Rect.fromLTWH(0, 0, size.width, size.height);
   canvas.drawRect(rect, background);

   Paint paint = Paint();
   paint.color = Colors.deepPurpleAccent;
   paint.strokeWidth = 70;
   paint.isAntiAlias = true;
   paint.strokeCap = StrokeCap.round;

   for(int x=0;x<points1.length-1;x++)
     {
       if(points1[x] != null && points1[x+1] != null)
       {
         canvas.drawLine(points1[x], points1[x+1], paint);
       }
       else if(points1[x] != null && points1[x+1] == null)
         {

           canvas.drawPoints(ui.PointMode.points,[points1[x]], paint);
         }
     }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }

}

class CPath2 extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path_0 = Path();
    path_0.moveTo(size.width*0.6738603,size.height);
    path_0.lineTo(size.width,size.height);
    path_0.lineTo(size.width*0.1934179,0);
    path_0.lineTo(size.width*0.08001079,0);
    path_0.lineTo(0,size.height*0.1078064);
    path_0.lineTo(size.width*0.6738603,size.height);
    path_0.close();
    return path_0;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    // TODO: implement shouldReclip
    return true;
  }

}
class MyPainter2 extends CustomPainter {
  List<Offset> points2;
  MyPainter2({this.points2});
  @override
  void paint(Canvas canvas, Size size) {
    Paint background = Paint()..color =  Colors.white;
    Rect rect = Rect.fromLTWH(0, 0, size.width, size.height);
    canvas.drawRect(rect, background);

    Paint paint = Paint();
    paint.color = Colors.deepPurpleAccent;
    paint.strokeWidth = 70;
    paint.isAntiAlias = true;
    paint.strokeCap = StrokeCap.round;

    for(int x=0;x<points2.length-1;x++)
    {
      if(points2[x] != null && points2[x+1] != null)
      {
        canvas.drawLine(points2[x], points2[x+1], paint);
      }
      else if(points2[x] != null && points2[x+1] == null)
      {

        canvas.drawPoints(ui.PointMode.points,[points2[x]], paint);
      }
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }

}

class CPath3 extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path_0 = Path();
    path_0.moveTo(size.width*0.9108546,0);
    path_0.lineTo(size.width*0.08746101,0);
    path_0.lineTo(0,size.height);
    path_0.lineTo(size.width,size.height*0.9771505);
    path_0.lineTo(size.width*0.9108546,0);
    path_0.close();
    return path_0;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    // TODO: implement shouldReclip
    return true;
  }

}
class MyPainter3 extends CustomPainter {
  List<Offset> points3;
  MyPainter3({this.points3});
  @override
  void paint(Canvas canvas, Size size) {
    Paint background = Paint()..color =  Colors.white;
    Rect rect = Rect.fromLTWH(0, 0, size.width, size.height);
    canvas.drawRect(rect, background);

    Paint paint = Paint();
    paint.color = Colors.deepPurpleAccent;
    paint.strokeWidth = 70;
    paint.isAntiAlias = true;
    paint.strokeCap = StrokeCap.round;

    for(int x=0;x<points3.length-1;x++)
    {
      if(points3[x] != null && points3[x+1] != null)
      {
        canvas.drawLine(points3[x], points3[x+1], paint);
      }
      else if(points3[x] != null && points3[x+1] == null)
      {

        canvas.drawPoints(ui.PointMode.points,[points3[x]], paint);
      }
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }

}





标签: flutterdrawingdraggablegesturedetector

解决方案


推荐阅读