我对颤振很陌生,正在尝试弄清楚如何在 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;
}
我用手势检测器尝试了下面的代码片段,但它不起作用。我尝试了一个侦听器,但没有得到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 工作。
重写KeyPathPainter
类的hitTest()
方法:
@override
bool hitTest(Offset position) {
// _path - is the same one we built in paint() method;
return _path.contains(position);
}
这将允许GestureDetector
检测路径内的水龙头,而不是整个CustomPaint
容器。尽管必须关闭_path
,因为没有办法(至少我知道(可以测试曲线上的命中。
我是通过谷歌搜索我遇到的一个问题而得出的。我的问题是我只是将画家包裹在一个手势检测器中,例如:
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,
);
用手势检测器包裹油漆应该可以完成这项工作。
GestureDetector(
onTapDown: (details) {
print("${details.globalPosition.dx}");
print("${details.globalPosition.dy}");
},
),
你应该有一个 CustomPaint 的孩子
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: YourAwesomePainter(),
child: Container(), // this line will solve the tap problem
);
}
将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
},
),
);
}
}
使用 LeafRenderObjectWidget 而不是 CustomPaint。
- LeafRenderObjectWidget 覆盖 createRenderObject 方法。
- createRenderObject 返回 RenderConscuredBox。
- RenderConscuredBox override handlerEvent/hitTestSelf/paint 方法。
可以在handleEvent(PointerEvent event, BoxHitTestEntry entry)
方法中实现手势识别器。
或
基于系统类扩展手势识别器VerticalDragGestureRecognizer/HorizontalDragGestureRecognizer/PanGestureRecognizer/...