我无法使用平移更新来获取手势检测器小部件上的实际本地位置
这是我的示例代码
new Center(
child new Container(
height: 150.0,
width: 150.0,
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(5.0),
color: Colors.white,
),
child: new GestureDetector(
onPanUpdate: (details) => onPanUpdate(context, details),
child: new CustomPaint(
painter: new MyPainter(
points: points,
limitBottom:height - 125.0,
limitTop: 10.0,
limitLeft: 5.0,
limitRight: width - 55.0
),
),
),
),
)
当我打印全局位置和局部位置的偏移量时,它们两个的值相同。结果是它被绘制在我的Container小部件外部。有什么我想得到的本地职位吗?
答案 0 :(得分:8)
我认为您正在使用类似的方法来获取本地位置:
RenderBox getBox = context.findRenderObject();
var local = getBox.globalToLocal(start.globalPosition);
这样做之后得到错误偏移的原因与您用来查找本地位置的context
有关。
如果您使用的是整个窗口小部件的上下文,那么实际上,您要做的是计算整个窗口小部件内的偏移量。即
YourWidget <-- context
Center
Container
GestureDetector
...
假设屏幕看起来像这样:
1__________________________
| | <--- YourWidget
| 2_________ |
| | gesture | |
| | detector| |
| | 3. | |
| |_________| |
| |
|__________________________|
其中1是整个小部件(和屏幕)的左上方,2是手势检测器的左上方,3是您点击的位置。
通过使用YourWidget的上下文,您正在根据1和3之间的差值来计算抽头的位置。如果1恰好位于屏幕的左上方,则结果将与全局坐标相匹配。 / p>
通过使用手势检测器上下文,您可以测量2到3之间的距离,这将为您提供所需的偏移量。
有两种方法可以解决此问题-您可以将GestureDetector包装在Builder小部件中,或者可以创建一个仅封装GestureDetector的新的有状态/无状态小部件。我个人建议创建一个新的小部件。
答案 1 :(得分:0)
感谢@rmtmckenzie,用StatelessWidget
包裹起来对我来说很好用
这是我的代码:
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(),
body: _Foo(),
);
}
}
class _Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onLongPressDragStart: (details) => _onLongPressDragStart(details, context),
onLongPressDragUpdate: (details) => _onLongPressDragUpdate(details, context),
onLongPressDragUp: (details) => _onLongPressDragUp(details, context),
child: FlareActor(
"assets/test.flr",
alignment: Alignment.center,
fit: BoxFit.contain,
),
);
}
void _onLongPressDragStart(GestureLongPressDragStartDetails details, BuildContext context) {
print('_onLongPressDragStart details: ${details.globalPosition}');
}
void _onLongPressDragUpdate(GestureLongPressDragUpdateDetails details, BuildContext context) {
var localTouchPosition = (context.findRenderObject() as RenderBox).globalToLocal(details.globalPosition);
print('_onLongPressDragUpdate details: ${details.globalPosition} - localTouchPosition: $localTouchPosition');
}
void _onLongPressDragUp(GestureLongPressDragUpDetails details, BuildContext context) {
print('_onLongPressDragUp details: ${details.globalPosition}');
}
}
重要的事情发生在_Foo
类中。
答案 2 :(得分:0)
我的“点击位置”被抵消时遇到了问题。我相信这是上述相同的问题。通过阅读有关键并在此处找到小部件的位置/大小,我能够解决此类似问题:
https://medium.com/@diegoveloper/flutter-widget-size-and-position-b0a9ffed9407
因此,我不必如上所述创建另一个窗口小部件或布局生成器,但是我可以添加一个全局键,然后通过使用来自键。很酷!
void _handleLongPress(LongPressStartDetails details) {
final RenderBox referenceBox = _keyRink.currentContext.findRenderObject();
var x = referenceBox.globalToLocal(details.globalPosition);
if (x == tapPosition) {
Vibration.vibrate(duration: 50);
setState(() {
_shots[_homeShotCount] = tapPosition;
});
}
}
这是我的主要脚手架,您可以在其中看到添加钥匙的位置。
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: GestureDetector(
key: _keyRink,
onTapDown: _getTapPosition,
onLongPressStart: _handleLongPress,
child: Stack(
children: <Widget>[
AnimatedOpacity(
duration: Duration(milliseconds: 2500),
opacity: _rinkOpacity,
child: Center(
child: Image.asset('assets/rink.png',
width: size.width, height: size.height, fit: BoxFit.fill),
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Transform.rotate(
angle: animationRotate.value,
child: Transform.scale(
scale: animationDrop.value,
child: FlatButton(
onPressed: null,
padding: EdgeInsets.all(0.0),
child: Image.asset('assets/puck.png'))),
)
],
),
),
CustomPaint(
painter: ShapesPainter(),
child: FractionallySizedBox(heightFactor: 1.0,widthFactor: 1.0,),
),
],
),
),
drawer: Drawer(
child: drawerItems,
),
);
}
答案 3 :(得分:0)
您可以使用 DragUpdateDetails.localPosition
获取 GestureDetector 的本地位置GestureDetector(
onPanUpdate: (DragUpdateDetails details) {
print('onPanUpdate');
print(details.localPosition);
},
)