我正在Flutter中实现Drawing App。我指的是this tutorial,但不知何故我被一个
卡住了简述:如您所见,我有两个容器。一个用于绘图,一个在下方,用于“在上方绘画”。但是要点超出了范围。我希望用户可以在上层容器中进行绘制。所以我的问题是- 如果手势检测超出了特定容器的范围,该如何取消呢?
代码段:
final GestureDetector paintGesture = GestureDetector(
onPanUpdate: (DragUpdateDetails details) {
setState(() {
RenderBox object = context.findRenderObject();
Offset _localPosition = object.localToGlobal(details.globalPosition);
_points = new List.from(_points)..add(_localPosition);
});
},
onPanEnd: (DragEndDetails details) {
_points.add(null);
},
child: sketchArea,
);
final Container sketchArea = Container(
//margin: EdgeInsets.all(1.0),
//alignment: Alignment.topLeft,
color: Colors.white,
child: new CustomPaint(
painter: new Signature(points: _points),
size: Size.infinite,
),
);
脚手架:
return new Scaffold(
body: Container(
child: Column(
children: <Widget>[
Expanded(
child: paintGesture,
),
Expanded(
child: Center(
child: Container(
child: Text(
_selectedInput,
style: TextStyle(
color: Colors.black,
fontSize: 40.0,
),
),
),
),
),
],
),
),
);
答案 0 :(得分:0)
我使用了来自this post的vovohost解决方案来获取我的Container
的坐标:
扩展名:
extension GlobalKeyExtension on GlobalKey {
Rect get globalPaintBounds {
final renderObject = currentContext?.findRenderObject();
var translation = renderObject?.getTransformTo(null)?.getTranslation();
if (translation != null && renderObject.paintBounds != null) {
return renderObject.paintBounds
.shift(Offset(translation.x, translation.y));
} else {
return null;
}
}
}
用法:
final containerKey = GlobalKey();
Rect get containerRect => containerKey.globalPaintBounds;
Container(
key: containerKey,
width: 100,
height: 50,
)
void printWidgetPosition() {
print('absolute coordinates on screen: ${containerRect}');
}
一旦获得坐标,就必须使用此方法在Offset
的范围内返回Container
:
Offset _offsetInBox(Offset globalOffset) {
// Y coordinate
double nearestY = 0;
if (globalOffset.dy >= containerRect.top &&
globalOffset.dy <= containerRect.bottom) {
nearestY = globalOffset.dy;
} else {
if ((containerRect.top - globalOffset.dy).abs() >
(containerRect.bottom - globalOffset.dy).abs()) {
nearestY = containerRect.bottom;
} else {
nearestY = containerRect.top;
}
}
// X coordinate
double nearestX = 0;
if (globalOffset.dx >= containerRect.left &&
globalOffset.dx <= containerRect.right) {
nearestX = globalOffset.dx;
} else {
if ((containerRect.left - globalOffset.dx).abs() >
(containerRect.right - globalOffset.dx).abs()) {
nearestX = containerRect.right;
} else {
nearestX = containerRect.left;
}
}
print(
"Global[${globalOffset.dx}, ${globalOffset.dy}], Found=[$nearestX, $nearestY]");
return Offset(nearestX, nearestY);
}
在您的GestureDetector上,像这样使用它:
final GestureDetector paintGesture = GestureDetector(
onPanUpdate: (DragUpdateDetails details) {
setState(() {
RenderBox renderBox = context.findRenderObject();
// Use the globalToLocal method if you want the local coordinates, not localToGlobal
Offset _localPosition = renderBox
.globalToLocal(_offsetInBox(details.globalPosition));
_points = List.from(_points)..add(_localPosition);
});
},
onPanEnd: (DragEndDetails details) {
_points.add(null);
},
child: sketchArea,
);
final Container sketchArea = Container(
key: containerKey,
color: Colors.white,
child: CustomPaint(
painter: Signature(points: _points),
size: Size.infinite,
),
);