flutter, Dart ) How to draw lines only using stylus pen (Samsung Galaxy Tab)

454 Views Asked by At

Im a flutter beginner and making a drawing app that can draw lines only with stylus device.

my test app can draw lines with finger and stylu but I want to implement the function that can draw lines only with a stylus.

I know there's a PointerData class and PointerDeviceKind.stylus enum. but I dont know how to use this class.

Here's my code and I used the provider.

OHHH I found the GestureRecognizer constructor and it says It's possible to limit this recognizer to a specific set of PointerDeviceKinds by providing the optional supportedDevices argument. haha but I have no idea how to apply this constructor to my code...

main.dart

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ChangeNotifierProvider(
          create: (context) => DrawingProvider(), child: BlankPage()),
    );
  }
}

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

  @override
  State<BlankPage> createState() => _BlankPageState();
}

class _BlankPageState extends State<BlankPage> {
  @override
  Widget build(BuildContext context) {
    var p = Provider.of<DrawingProvider>(context);
    return GestureDetector(
      child: Scaffold(
          body: Column(
        children: [
          Row(
            children: [
              penWidget(p: p),
              colorWidget(context: context, color: Colors.black),
            ],
          ),
          Expanded(
            child: Stack(
              children: [
                Center(
                  child: Image(
                    image: AssetImage('image/image1.jpg'),
                    fit: BoxFit.cover,
                  ),
                ),
                Positioned.fill(
                  child: CustomPaint(
                    painter: DrawingPainter(p.lines),
                  ),
                ),
                GestureDetector(
                  behavior: HitTestBehavior.translucent,
                  onPanDown: (s) {
                    p.penMode ? p.penDrawStart(s.localPosition) : null;
                  },
                  onPanUpdate: (s) {
                    p.penMode ? p.penDrawing(s.localPosition) : null;
                  },
                  child: Container(
                    child: Listener(
                      behavior: HitTestBehavior.opaque,
                      onPointerDown: (_) {
                        print("컨테이너 눌림");
                      },
                    ),
                  ),
                ),
              ],
            ),
          ),
        ],
      )),
    );
  }
}

class DrawingPainter extends CustomPainter {
  DrawingPainter(this.lines);

  final List<List<DotInfo>> lines;

  @override
  void paint(Canvas canvas, Size size) {
    for (var oneLine in lines) {
      Color? color;
      double? size;
      var path = Path();
      var l = <Offset>[];
      for (var oneDot in oneLine) {
        color ??= oneDot.color;
        size ??= oneDot.size;
        l.add(oneDot.offset);
      }
      path.addPolygon(l, false);
      canvas.drawPath(
          path,
          Paint()
            ..color = color!
            ..strokeWidth = size!
            ..strokeCap = StrokeCap.round
            ..style = PaintingStyle.stroke
            ..isAntiAlias = true);
    }
  }

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

drawing_provider.dart

class DrawingProvider extends ChangeNotifier {
final lines = <List<DotInfo>>[];

double _penSize = 3;
double get penSize => _penSize;



 Color _selectedColor = Colors.black;
 Color get selectedColor => _selectedColor;

 bool _penMode = false;
 bool get penMode => _penMode;

  void changePenMode() {
    _penMode = !_penMode;
    print("penMode is called : ${penMode} ");
    _eraseMode = false;
    _highlighterMode = false;
    notifyListeners();
  }

void penDrawStart(Offset offset) {
    var oneLine = <DotInfo>[];
    oneLine.add(DotInfo(offset, penSize, _selectedColor));
    lines.add(oneLine);
    notifyListeners();
  }

  void penDrawing(Offset offset) {
    lines.last.add(DotInfo(offset, penSize, _selectedColor));
    print("Drawing");
    notifyListeners();
  }
1

There are 1 best solutions below

0
KRBILN On

I solved this problem by using Listener widget, onPointerDown and onPointerMove, onPointerCancel

if(s.kind == PointerDeviceKind.stylus) {
  p.penMode ? p.penDrawStart(s.localPosition) : null;
  p.highlighterMode ? p.highlighterDrawStart(s.localPostion) : null;