我一直在从事一个项目,该项目需要我根据移动设备的orientation
更改屏幕小部件。
例如,
在portrait
方向的情况下,我需要显示一个小部件(假设是纵向小部件),在landscape
方向的情况下,我需要显示另一个小部件(将其称为横向小部件)。
我用过OrientationBuilder
实际问题:更改方向时,不会关闭所有Dialogs
和OptionMenu
或任何其他Popup类型的小部件。如何在方向改变时关闭它们?
重现问题的步骤:
OptionMenu
Popuped
小部件仍然可见。示例应用代码:
// main.dart
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return OrientationBuilder(builder: (context, orientation) {
bool isLandscape = orientation == Orientation.landscape;
return isLandscape ? Landscape() : Portrait();
});
}
}
class Portrait extends StatefulWidget {
@override
_PortraitState createState() => _PortraitState();
}
class _PortraitState extends State<Portrait> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: buildTitle(),
actions: <Widget>[_buildOptionMenu(context)],
),
body: GestureDetector(
onLongPress: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: buildTitle(),
),
);
},
child: Container(
color: Colors.blue.withOpacity(0.4),
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Center(
child: buildTitle(),
),
],
),
),
),
);
}
Widget _buildOptionMenu(BuildContext context) {
return PopupMenuButton(itemBuilder: (context) {
var list = <String>['Portrait-Item-1', 'Portrait-Item-2'];
return list
.map<PopupMenuEntry<String>>(
(e) => PopupMenuItem<String>(
child: Text(e),
),
)
.toList();
});
}
Text buildTitle() => Text('Portrait');
}
class Landscape extends StatefulWidget {
@override
_LandscapeState createState() => _LandscapeState();
}
class _LandscapeState extends State<Landscape> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: buildTitle(),
actions: <Widget>[_buildOptionMenu(context)],
),
body: GestureDetector(
onLongPress: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: buildTitle(),
),
);
},
child: Container(
color: Colors.orange.withOpacity(0.3),
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Center(
child: buildTitle(),
),
],
),
),
),
);
}
Text buildTitle() => Text('Landscape');
Widget _buildOptionMenu(BuildContext context) {
return PopupMenuButton(itemBuilder: (context) {
var list = <String>[
'Landscape-Item-1',
'Landscape-Item-2',
'Landscape-Item-3',
];
return list
.map<PopupMenuEntry<String>>(
(e) => PopupMenuItem<String>(
child: Text(e),
),
)
.toList();
});
}
}
我找不到任何可行的解决方案。有一些解决方案需要侦听方向更改以及基于新方向的推送/弹出窗口小部件。
但是要使用太多的代码,需要在纵向和横向小部件中添加相同类型的代码。如果我需要处理其他方向(例如反向肖像和反向风景),这也是不可扩展的。
感谢您的帮助。如果您认为缺少某些内容,请在评论中通知我,我将尽快更新所需的详细信息。
提前感谢。
作为选项
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return OrientationBuilder(builder: (context, orientation) {
bool isLandscape = orientation == Orientation.landscape;
Navigator.of(context).popUntil(ModalRoute.withName('/')); // add this line
return isLandscape ? Landscape() : Portrait();
});
}
}
当您添加导航时,只需将根路径名称'/'更改为您的路径名称