在Flutter中,如何使画布画家对象只能在单击时拖动

e5nqia27  于 2023-03-13  发布在  Flutter
关注(0)|答案(1)|浏览(121)

描述我正在创建算盘在Flutter。珠子(绿色圆圈),是由自定义画家对象。

The current UI

问题当我拖动珠子或只是拖动其他对象时,珠子也被拖动。如何限制珠子的移动,使珠子仅在我按下并拖动时移动?

我将画布指针对象 Package 在GestureDetector中,以便仅在存在onVerticalDragUpdate时进行检测

import 'package:abacus_game/functions.dart';
import 'package:abacus_game/widget/bar.dart';
import 'package:abacus_game/widget/frame.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeLeft,
  ]).then((value) => runApp(MyApp()));
  runApp(const MyApp());
}

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyPainter(),
    );
  }
}

class MyPainter extends StatefulWidget {
  @override
  State<MyPainter> createState() => _MyPainterState();
}

class _MyPainterState extends State<MyPainter> {
  Offset _offset = new Offset(0, 0);
  bool isFirst = true;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    if (isFirst) {
      _offset =
          new Offset(getScreenWidth(context) / 2, getScreenHeight(context) / 2);
    }

    return Scaffold(
      appBar: AppBar(
        title: Text('Abacus'),
      ),
      body: Center(
        child: Container(
          decoration:
              BoxDecoration(border: Border.all(color: Colors.blueAccent)),
          child: Stack(
            alignment: Alignment.center,
            children: [
              Container(
                width: 10,
                height: 400,
                color: Colors.brown,
              ),
              GestureDetector(
                onVerticalDragUpdate: (details) {
                  // print(details.localPosition);
                  setState(() {
                    isFirst = false;
                    _offset = details.localPosition;
                  });
                },
                child: CustomPaint(
                  painter: BeadPainter(_offset, getScreenWidth(context)),
                  child: GestureDetector(
                    child: Container(),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class BeadPainter extends CustomPainter {
  final Offset offset;
  final double screenWidth;

  BeadPainter(this.offset, this.screenWidth) : super();

  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.teal
      ..strokeWidth = 5
      ..strokeCap = StrokeCap.round;

    Offset newOffset = new Offset(screenWidth / 2, offset.dy);

    canvas.drawCircle(newOffset, 20, paint);
  }

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

tcbh2hod1#

要使画布画家对象仅在单击时可拖动,可以使用Flutter中的GestureDetector小部件。GestureDetector小部件提供了一种检测不同类型手势的方法,包括点击和拖动。
下面是一个如何在Flutter中实现此功能的示例:
1.首先,创建一个StatefulWidget来保存画布绘制器对象的状态:

class DraggablePainter extends StatefulWidget {
  @override
  _DraggablePainterState createState() => _DraggablePainterState();
}

class _DraggablePainterState extends State<DraggablePainter> {
  // State variables for the position of the painter object
  Offset _position = Offset(0, 0);

  // Function to update the position of the painter object
  void _updatePosition(DragUpdateDetails details) {
    setState(() {
      _position += details.delta;
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onPanUpdate: _updatePosition,
      child: CustomPaint(
        painter: MyPainter(_position),
      ),
    );
  }
}

1.在本例中,MyPainter类用于在画布上绘制画家对象。画家对象的位置存储在_position变量中,当用户使用_updatePosition()函数拖动对象时,该变量会更新。

  1. GestureDetector小部件用于检测拖拽手势,当用户拖拽对象时调用onPanUpdate()回调函数,它调用_updatePosition()函数来更新对象的位置。
    1.最后,使用CustomPaint小部件在画布上绘制painter对象,painter对象使用MyPainter类创建,并将_position变量传递给构造函数以设置其初始位置。

相关问题