获取相对于小部件的点击位置
Get Tap Position Relative to Widget
我正在尝试制作一个 Flutter 小部件来设置温度,看起来像恒温器旋钮。我已经扩展了 CustomPainter 以实际在屏幕上绘制它,现在我正在尝试设置抓取功能以便用户可以旋转它。
我可以使用 GestureDetector 小部件在用户触摸屏幕时获得回调,但我需要知道它相对于旋钮中心的位置。不幸的是,GestureDetector 提供的位置是绝对坐标,而 canvas 相对于小部件的原点工作。有什么方法可以将这些坐标中的一个转换为另一个?
这意味着我需要:
1) 一种获取相对于 CustomPainter 小部件的点击位置的方法
2) 一种获取 CustomPainter 小部件的绝对位置的方法
我找不到可以提供其中任何一个的 API。这样的API存在吗?
上下文:https://github.com/dgp1130/thermo/blob/master/lib/widgets/temp_picker.dart
目前的方式是,旋转恒温器可以工作,但由于应用栏的高度,触摸 "center" 实际上大约在实际中心上方的一半。
谢谢
您可以使用 RenderBox.globalToLocal
method. To get the RenderBox
, you can call findRenderObject
on the BuildContext
.
将全局坐标转换为局部坐标
--- a/lib/widgets/temp_picker.dart
+++ b/lib/widgets/temp_picker.dart
@@ -41,7 +41,12 @@ class _TempPickerState extends State<TempPicker> {
return new Container(
constraints: new BoxConstraints.expand(),
child: new GestureDetector(
- onPanUpdate: (details) => setState(() => _tapPos = details.globalPosition),
+ onPanUpdate: (details) {
+ setState(() {
+ RenderBox box = context.findRenderObject();
+ _tapPos = box.globalToLocal(details.globalPosition);
+ });
+ },
child: new CustomPaint(
painter: new _TempPainter(
minValue: widget.minValue,
虽然这不太正确,因为当设备旋转并且 TempPicker
小部件的大小发生变化时,它可能会出现意外行为。我建议您计算 getAngleFromPosition
的结果并将其保存在 onPanUpdate
中,并将该角度值传递给 _TempPainter
构造函数,而不是将本地偏移量存储在 _tapPos
中。这样,只要用户当前未触摸屏幕,当屏幕尺寸发生变化时角度将保持不变。
您可以使用 TapDownDetails 的 localposition 属性,如下所示:
GestureDetector(
onTapDown: (details) {
//local position
print(details.localPosition);
//global position
print(details.globalPosition);
},
),
我正在尝试制作一个 Flutter 小部件来设置温度,看起来像恒温器旋钮。我已经扩展了 CustomPainter 以实际在屏幕上绘制它,现在我正在尝试设置抓取功能以便用户可以旋转它。
我可以使用 GestureDetector 小部件在用户触摸屏幕时获得回调,但我需要知道它相对于旋钮中心的位置。不幸的是,GestureDetector 提供的位置是绝对坐标,而 canvas 相对于小部件的原点工作。有什么方法可以将这些坐标中的一个转换为另一个?
这意味着我需要:
1) 一种获取相对于 CustomPainter 小部件的点击位置的方法
2) 一种获取 CustomPainter 小部件的绝对位置的方法
我找不到可以提供其中任何一个的 API。这样的API存在吗?
上下文:https://github.com/dgp1130/thermo/blob/master/lib/widgets/temp_picker.dart
目前的方式是,旋转恒温器可以工作,但由于应用栏的高度,触摸 "center" 实际上大约在实际中心上方的一半。
谢谢
您可以使用 RenderBox.globalToLocal
method. To get the RenderBox
, you can call findRenderObject
on the BuildContext
.
--- a/lib/widgets/temp_picker.dart
+++ b/lib/widgets/temp_picker.dart
@@ -41,7 +41,12 @@ class _TempPickerState extends State<TempPicker> {
return new Container(
constraints: new BoxConstraints.expand(),
child: new GestureDetector(
- onPanUpdate: (details) => setState(() => _tapPos = details.globalPosition),
+ onPanUpdate: (details) {
+ setState(() {
+ RenderBox box = context.findRenderObject();
+ _tapPos = box.globalToLocal(details.globalPosition);
+ });
+ },
child: new CustomPaint(
painter: new _TempPainter(
minValue: widget.minValue,
虽然这不太正确,因为当设备旋转并且 TempPicker
小部件的大小发生变化时,它可能会出现意外行为。我建议您计算 getAngleFromPosition
的结果并将其保存在 onPanUpdate
中,并将该角度值传递给 _TempPainter
构造函数,而不是将本地偏移量存储在 _tapPos
中。这样,只要用户当前未触摸屏幕,当屏幕尺寸发生变化时角度将保持不变。
您可以使用 TapDownDetails 的 localposition 属性,如下所示:
GestureDetector(
onTapDown: (details) {
//local position
print(details.localPosition);
//global position
print(details.globalPosition);
},
),