OrientationBuilder
在完全转换后报告方向更改,然后在此之后进行重建。
在定向开始之前,有没有办法采取行动?我不是要抢先轮换,而是要同时进行更改,而不是在此之后进行更改。
目标:
挑战,如何在3发生之前实现点2?
最佳答案
是的,您可以通过覆盖 WidgetsBindingObserver
来使用didChangeMetrics
来获取方向更改早于。
如何使用didChangeMetrics
您可以简单地在有状态的小部件的 WidgetBindingObserver
implementation中混合State
:
class _FooState extends State with WidgetsBindingObserver {
@override
void didChangeMetrics() {
// This will be triggered by changes in orientation.
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}
确定方向方向由可用尺寸的长宽比确定。这意味着您可以使用以下代码在
didChangeMetrics
中获得方向:final orientation = WidgetsBinding.instance.window.physicalSize
.aspectRatio > 1 ? Orientation.landscape : Orientation.portrait;
例我构建了一个示例
StatefulWidget
,将OrientationBuilder
回调与didChangeMetrics
进行了比较:import 'package:flutter/material.dart';
void main() {
runApp(OrientationListener());
}
class OrientationListener extends StatefulWidget {
@override
_OrientationListenerState createState() => _OrientationListenerState();
}
class _OrientationListenerState extends State<OrientationListener>
with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeMetrics() {
print('$WidgetsBindingObserver metrics changed ${DateTime.now()}: '
'${WidgetsBinding.instance.window.physicalSize.aspectRatio > 1 ? Orientation.landscape : Orientation.portrait}');
}
@override
Widget build(BuildContext context) {
return MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
child: OrientationBuilder(
builder: (context, orientation) {
print('$OrientationBuilder rebuild ${DateTime.now()}: $orientation');
return Container();
},
),
);
}
}
结果运行此示例将显示以下两个功能的时间:
WidgetsBindingObserver metrics changed 2020-08-22 14:47:01.690172: Orientation.portrait
WidgetsBindingObserver metrics changed 2020-08-22 14:47:01.706574: Orientation.landscape
OrientationBuilder rebuild 2020-08-22 14:47:01.760589: Orientation.landscape
WidgetsBindingObserver metrics changed 2020-08-22 14:47:06.537083: Orientation.landscape
WidgetsBindingObserver metrics changed 2020-08-22 14:47:06.549545: Orientation.portrait
OrientationBuilder rebuild 2020-08-22 14:47:06.603859: Orientation.portrait
WidgetsBindingObserver metrics changed 2020-08-22 14:47:10.423787: Orientation.portrait
WidgetsBindingObserver metrics changed 2020-08-22 14:47:10.442866: Orientation.landscape
OrientationBuilder rebuild 2020-08-22 14:47:10.501729: Orientation.landscape
WidgetsBindingObserver metrics changed 2020-08-22 14:47:13.639545: Orientation.landscape
WidgetsBindingObserver metrics changed 2020-08-22 14:47:13.658906: Orientation.landscape
WidgetsBindingObserver metrics changed 2020-08-22 14:47:13.672025: Orientation.portrait
OrientationBuilder rebuild 2020-08-22 14:47:13.730771: Orientation.portrait
因此,就我而言,检测的差异约为0.06
秒。观察结果
从上面可以看到,差异不明显(我会说)。因此,我什至不确定这对您是否有用。
此外,我观察到
OrientationBuilder
回调实际上在设备旋转的开始处实际上称为-至少在我的Android仿真器上。这意味着您可以在轮换发生之前重建UI。我希望这对您有帮助:)