【问题标题】:How do I get to tap on a CustomPaint path in Flutter using GestureDetect?如何使用 GestureDetect 在 Flutter 中点击 CustomPaint 路径?
【发布时间】:2019-07-18 17:59:28
【问题描述】:

我是 Flutter 的新手,正在尝试弄清楚如何在 CustomPaint 路径上检测到手势。由于某种原因,我可以点击许多其他东西,但不能点击路径......我该如何让它工作?到目前为止,我的代码如下。

import 'package:flutter/material.dart';

void main() => runApp(MbiraShapes());

class MbiraShapes extends StatefulWidget {
    @override
  _MbiraShapesState createState() => _MbiraShapesState();
}

class _MbiraShapesState extends State<MbiraShapes>{

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Mbira Shapes',
        home: PathExample());
  }
}

class PathExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: KeyPathPainter(),
    );
  }
}

class KeyPathPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint lineDrawer = Paint()
      ..color = Colors.blue
      ..strokeWidth = 8.0;

    Path path = Path()
// Moves to starting point
      ..moveTo(50, 50)
      //draw lines passing through xc, yc to end at x,y
      ..quadraticBezierTo(77, 370, 50, 750)
      ..quadraticBezierTo(100, 775, 150, 750)
      ..quadraticBezierTo(110, 440, 75, 50);
    //close shape from last point
    path.close();
    canvas.drawPath(path, lineDrawer);

    Path path2 = Path()
// Moves to starting point
      ..moveTo(250, 50)
      //draw lines passing through xc, yc to end at x,y
      ..quadraticBezierTo(280, 350, 270, 675)
      ..quadraticBezierTo(290, 750, 350, 750)
      ..quadraticBezierTo(365, 710, 345, 600)
      ..quadraticBezierTo(320, 450, 270, 50);
    //close shape from last point
    path2.close();
    canvas.drawPath(path2, lineDrawer);
  }

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

我用 GestureDetector 尝试了下面的 sn-p,但它不起作用。 我尝试了一个监听器,但对 onPointerDown 没有响应,仅对 onPointerMove 有响应,但我需要一个点击动作,而不是移动动作。

@override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
  
        title: Text("widget.title)"),
      ),
      
      body: Center(
        child: GestureDetector(
          child: CustomPaint(
            painter: KeyPathPainter(),
            child: Container()),
          onTap: () {
            print("tapped the key");
          },
        ),
      ),
    );
  }

我只是想点击一个键并得到响应,最后会发出声音,但现在,我只是想弄清楚如何让 onTap 工作。

【问题讨论】:

  • 我为此创建了一个库:pub.dev/packages/touchable,它可以让您为在画布上绘制的每个单独对象添加手势回调。

标签: flutter dart path gesturedetector custom-painting


【解决方案1】:

您必须覆盖 KeyPathPainter 类的 hitTest() 方法:

@override
bool hitTest(Offset position) {
    // _path - is the same one we built in paint() method;
    return _path.contains(position);
}

这将允许GestureDetector 检测路径内的点击,而不是整个CustomPaint 容器。尽管_path 必须关闭,因为没有办法——至少据我所知——无法测试曲线上的命中。

【讨论】:

    【解决方案2】:

    用手势检测器包裹你的颜料应该可以完成这项工作。

     GestureDetector(
        onTapDown: (details) {
             print("${details.globalPosition.dx}");
             print("${details.globalPosition.dy}");
         },
      ),
    

    【讨论】:

    • 嗨,对不起,我不明白,我认为那是我已经对上面的第二个 sn-p 所做的,在 CustomPaint 和 GestureDetector 内有子 KeyPainter .. 这不起作用......请向我解释我哪里弄错了
    • 我正在测试你的代码,它可以工作,它检测到手势
    【解决方案3】:

    我是通过谷歌搜索我遇到的问题得出的。我的问题是我只是将 Painter 包装在手势检测器中,例如:

    GestureDetector(
          child: CustomPaint(
            painter: CustomPainter(),
          ),
    
          onTapDown: _handleTapDown,
    );
    

    解决方案是我需要一个带有颜色的Container,包裹自定义画家,如下所示:

    return GestureDetector(
          child: Container(
            width: 300,
            height: 300,
            color: Colors.white,
            child: CustomPaint(
              painter: CustomPainter(),
            ),
          ),
    
          onTapDown: _handleTapDown,
    );
    

    【讨论】:

      【解决方案4】:

      您需要将GestureDetector 作为CustomPainter 的子级。在你的情况下:

      class PathExample extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return CustomPaint(
            painter: KeyPathPainter(),
            // Add 5 following lines
            child: GestureDetector(
              onTap: () {
                // Handle your tap here
              },
            ),
          );
        }
      }
      

      【讨论】:

        【解决方案5】:

        你应该有一个 CustomPaint 的孩子

           @override
           Widget build(BuildContext context) {
             return CustomPaint(
               painter: KeyPathPainter(),
               child: Container(), // this line will solve the tap problem
            );
           }
        

        【讨论】:

          猜你喜欢
          • 2022-11-13
          • 1970-01-01
          • 2018-12-02
          • 2022-10-19
          • 2020-01-12
          • 2022-07-27
          • 2021-10-04
          • 2016-11-22
          • 1970-01-01
          相关资源
          最近更新 更多