如何检测颤动中的设备旋转(方向变化)?
我的应用程序具有可拖动的浮动动作按钮,可以在屏幕上移动到任何地方,并在掉落时留在该位置。 该按钮的代码来自Blogspot而非我的代码。 问题是,因为一切都设置在肖像模式下,并且在旋转发生时没有检测到,因此当设备从肖像模式旋转到景观模式时,该按钮可能无法到达(如果按钮以前在屏幕的下半部分在肖像模式)。
无论如何,是否有检测以前的方向以便在旋转时再次设置按钮的偏移?
这是您所看到的浮动按钮类/小部件的代码
import 'package:flutter/material.dart';
class DraggableFloatingActionButton extends StatefulWidget {
final Widget child;
final double deviceWidth;
final double deviceHeight;
final Function onPressed;
final GlobalKey parentKey;
DraggableFloatingActionButton({
required this.child,
required this.deviceWidth,
required this.deviceHeight,
required this.onPressed,
required this.parentKey,
});
@override
State<StatefulWidget> createState() => _DraggableFloatingActionButtonState();
}
class _DraggableFloatingActionButtonState extends State<DraggableFloatingActionButton> {
final GlobalKey _key = GlobalKey();
bool _isDragging = false;
late Offset _offset;
late Offset _minOffset;
late Offset _maxOffset;
@override
void initState() {
_offset = Offset(widget.deviceWidth * 0.8, widget.deviceHeight * 0.75);
WidgetsBinding.instance.addPostFrameCallback(_setBoundary);
super.initState();
}
void _setBoundary(_) {
final RenderBox parentRenderBox =
widget.parentKey.currentContext?.findRenderObject() as RenderBox;
final RenderBox renderBox = _key.currentContext?.findRenderObject() as RenderBox;
try {
final Size parentSize = parentRenderBox.size;
final Size size = renderBox.size;
setState(() {
_minOffset = const Offset(0, 0);
_maxOffset = Offset(parentSize.width - size.width, parentSize.height - size.height);
});
} catch (e) {
print('catch: $e');
}
}
void _updatePosition(PointerMoveEvent pointerMoveEvent) {
double newOffsetX = _offset.dx + pointerMoveEvent.delta.dx;
double newOffsetY = _offset.dy + pointerMoveEvent.delta.dy;
if (newOffsetX < _minOffset.dx) {
newOffsetX = _minOffset.dx;
} else if (newOffsetX > _maxOffset.dx) {
newOffsetX = _maxOffset.dx;
}
if (newOffsetY < _minOffset.dy) {
newOffsetY = _minOffset.dy;
} else if (newOffsetY > _maxOffset.dy) {
newOffsetY = _maxOffset.dy;
}
setState(() {
_offset = Offset(newOffsetX, newOffsetY);
});
}
@override
Widget build(BuildContext context) {
return Positioned(
left: _offset.dx,
top: _offset.dy,
child: Listener(
onPointerMove: (PointerMoveEvent pointerMoveEvent) {
_updatePosition(pointerMoveEvent);
setState(() {
_isDragging = true;
});
},
onPointerUp: (PointerUpEvent pointerUpEvent) {
print('onPointerUp');
if (_isDragging) {
setState(() {
_isDragging = false;
});
} else {
widget.onPressed();
}
},
child: Container(
key: _key,
child: widget.child,
),
),
);
}
}
,它仅在Initstate功能中一次基于肖像模式设置按钮的偏移量,并且不处理旋转。
我目前能想到的漫步只是在另一个浮动按钮专门设置为景观模式 。
预先感谢您的任何答案。
My app has a draggable floating action button that could move everywhere on the screen and stay at that position when being dropped.
The code for the button is from a blogspot and not mine.
The problem is, since everything is set in portrait mode, and there is no detection when rotation occurs, the button could be unreachable when device rotates from portrait mode to landscape mode (if the button was previously on the bottom half of the screen in portrait mode).
Is there anyway to detect previous orientation in order to set the offset for the button again when it rotates?
Here is the code for the floating button class/widget
import 'package:flutter/material.dart';
class DraggableFloatingActionButton extends StatefulWidget {
final Widget child;
final double deviceWidth;
final double deviceHeight;
final Function onPressed;
final GlobalKey parentKey;
DraggableFloatingActionButton({
required this.child,
required this.deviceWidth,
required this.deviceHeight,
required this.onPressed,
required this.parentKey,
});
@override
State<StatefulWidget> createState() => _DraggableFloatingActionButtonState();
}
class _DraggableFloatingActionButtonState extends State<DraggableFloatingActionButton> {
final GlobalKey _key = GlobalKey();
bool _isDragging = false;
late Offset _offset;
late Offset _minOffset;
late Offset _maxOffset;
@override
void initState() {
_offset = Offset(widget.deviceWidth * 0.8, widget.deviceHeight * 0.75);
WidgetsBinding.instance.addPostFrameCallback(_setBoundary);
super.initState();
}
void _setBoundary(_) {
final RenderBox parentRenderBox =
widget.parentKey.currentContext?.findRenderObject() as RenderBox;
final RenderBox renderBox = _key.currentContext?.findRenderObject() as RenderBox;
try {
final Size parentSize = parentRenderBox.size;
final Size size = renderBox.size;
setState(() {
_minOffset = const Offset(0, 0);
_maxOffset = Offset(parentSize.width - size.width, parentSize.height - size.height);
});
} catch (e) {
print('catch: $e');
}
}
void _updatePosition(PointerMoveEvent pointerMoveEvent) {
double newOffsetX = _offset.dx + pointerMoveEvent.delta.dx;
double newOffsetY = _offset.dy + pointerMoveEvent.delta.dy;
if (newOffsetX < _minOffset.dx) {
newOffsetX = _minOffset.dx;
} else if (newOffsetX > _maxOffset.dx) {
newOffsetX = _maxOffset.dx;
}
if (newOffsetY < _minOffset.dy) {
newOffsetY = _minOffset.dy;
} else if (newOffsetY > _maxOffset.dy) {
newOffsetY = _maxOffset.dy;
}
setState(() {
_offset = Offset(newOffsetX, newOffsetY);
});
}
@override
Widget build(BuildContext context) {
return Positioned(
left: _offset.dx,
top: _offset.dy,
child: Listener(
onPointerMove: (PointerMoveEvent pointerMoveEvent) {
_updatePosition(pointerMoveEvent);
setState(() {
_isDragging = true;
});
},
onPointerUp: (PointerUpEvent pointerUpEvent) {
print('onPointerUp');
if (_isDragging) {
setState(() {
_isDragging = false;
});
} else {
widget.onPressed();
}
},
child: Container(
key: _key,
child: widget.child,
),
),
);
}
}
As you can see, it only sets the button's offset based on portrait mode once in initState function, and doesn't deal with rotation.
A walk around that I could think of at this moment is just having another floating button specifically set for landscape mode.
Thank you in advance for any answer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好的,所以我仍然不知道如何检测旋转,但是我的走动是有效的。
我要做的就是为景观浮动按钮创建另一个类(小部件)。
在主要的情况下,检查设备方向以使用浮动按钮肖像类或景观类。
我在景观按钮类中更改的唯一一件事
从
是
Ok, so I still don't know how to detect rotation, but my walk around works.
All I do is create another class(widget) for a landscape floating button.
In main, check device orientation to use either the floating button portrait class or landscape class.
The only thing that I change in the landscape button class is
from
to
您不应该关心方向。您应该使用
LayoutBuilder
之类的东西来确定可用的空间,并根据此做出断点决策。如果设备空间更改,LayoutBuilder将立即更新,并且您应该通过另一种布局对此做出反应。You shouldn't care about orientation. You should use something like
LayoutBuilder
to determine your space available, and make breakpoint decisions based on that. LayoutBuilder will update immediately if the device space changes, and you should react to that by doing another layout.