部分屏幕的颤动导航
Flutter navigation for part of screen
如何将一个小部件推送到另一个小部件的框架中?例如,我有一个包含 2 个容器的列,其中每个容器占据屏幕的一半。我想做一个导航,例如仅在底部容器中。当容器视图拥有自己的 UINavigationController 时,与 iOS 中的逻辑相同。
据我所知,MaterialPageRoute 只能将小部件推送到全屏,并且没有任何其他路线 类,除了抽象路线。也许我应该创建自己的 ModalRoute/TransitionRoute?
子类
您可以使用 Navigator 小部件在您的应用程序中提供任意数量的独立导航器。每个 Navigator 都将维护它自己的导航堆栈。例如,如果您想垂直拆分您的应用程序,每一半都有自己的导航堆栈:
Column(
children: <Widget>[
Navigator(...),
Navigator(...)
]
)
如果你这样做,你应该考虑你想如何处理 Android 后退按钮(现在你的应用程序中技术上有 3 个导航器)。默认情况下,它只会监听您的根导航器,因此您必须在小部件层次结构中的某处提供一个 WillPopScope 小部件,以捕获后退按钮事件并从适当的导航器中弹出。
一个可能的解决方案是在屏幕的那部分创建一个新的 MaterialApp 并像常规应用程序一样处理那里的所有内容(只是屏幕尺寸不同),如下所示:
Column(
children: <Widget>[
Container(
height: constraints.maxHeight * 0.5,
width: constraints.maxWidth,
),
Container(
height: constraints.maxHeight * 0.5,
width: constraints.maxWidth,
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color.fromRGBO(86, 86, 86, 1.00),
),
initialRoute: '/W1',
routes: {
'/W1': (context) => WidgetOne(),
'/W2': (context) => WidgetTwo(),
})),
],
),
然后像这样使用小部件处理路由:
class WidgetOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.pushNamed(context, '/W2');
},
child: Container(color: Colors.green));
}
}
}
class WidgetTwo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.pushNamed(context, '/W1');
},
child: Container(color: Colors.pink));
}
}
}
结果:
https://i.stack.imgur.com/qyJ5N.gif
您可以使用 Navigator 作为您想要制作的特定部分的子项。
如果有的话,我使用 WillPopScope 返回到上一个屏幕。
并确保使用 GlobalKey() 来分隔每个导航器并为其提供唯一的密钥。
我的代码:
var keyOne = GlobalKey<NavigatorState>();
var keyTwo = GlobalKey<NavigatorState>();
return Column(
children: [
Expanded(
child: Container(
child: WillPopScope(
onWillPop: () async => !await keyOne.currentState.maybePop(),
child: Navigator(
key: keyOne,
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(
builder: (context) => ScreenOne(),
);
},
),
),
),
),
Expanded(
child: Container(
child: WillPopScope(
onWillPop: () async => !await keyTwo.currentState.maybePop(),
child: Navigator(
key: keyTwo,
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(
builder: (context) => ScreenTwo(),
);
},
),
),
),
),
],
);
如何将一个小部件推送到另一个小部件的框架中?例如,我有一个包含 2 个容器的列,其中每个容器占据屏幕的一半。我想做一个导航,例如仅在底部容器中。当容器视图拥有自己的 UINavigationController 时,与 iOS 中的逻辑相同。
据我所知,MaterialPageRoute 只能将小部件推送到全屏,并且没有任何其他路线 类,除了抽象路线。也许我应该创建自己的 ModalRoute/TransitionRoute?
子类您可以使用 Navigator 小部件在您的应用程序中提供任意数量的独立导航器。每个 Navigator 都将维护它自己的导航堆栈。例如,如果您想垂直拆分您的应用程序,每一半都有自己的导航堆栈:
Column(
children: <Widget>[
Navigator(...),
Navigator(...)
]
)
如果你这样做,你应该考虑你想如何处理 Android 后退按钮(现在你的应用程序中技术上有 3 个导航器)。默认情况下,它只会监听您的根导航器,因此您必须在小部件层次结构中的某处提供一个 WillPopScope 小部件,以捕获后退按钮事件并从适当的导航器中弹出。
一个可能的解决方案是在屏幕的那部分创建一个新的 MaterialApp 并像常规应用程序一样处理那里的所有内容(只是屏幕尺寸不同),如下所示:
Column(
children: <Widget>[
Container(
height: constraints.maxHeight * 0.5,
width: constraints.maxWidth,
),
Container(
height: constraints.maxHeight * 0.5,
width: constraints.maxWidth,
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color.fromRGBO(86, 86, 86, 1.00),
),
initialRoute: '/W1',
routes: {
'/W1': (context) => WidgetOne(),
'/W2': (context) => WidgetTwo(),
})),
],
),
然后像这样使用小部件处理路由:
class WidgetOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.pushNamed(context, '/W2');
},
child: Container(color: Colors.green));
}
}
}
class WidgetTwo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.pushNamed(context, '/W1');
},
child: Container(color: Colors.pink));
}
}
}
结果: https://i.stack.imgur.com/qyJ5N.gif
您可以使用 Navigator 作为您想要制作的特定部分的子项。 如果有的话,我使用 WillPopScope 返回到上一个屏幕。 并确保使用 GlobalKey() 来分隔每个导航器并为其提供唯一的密钥。 我的代码:
var keyOne = GlobalKey<NavigatorState>();
var keyTwo = GlobalKey<NavigatorState>();
return Column(
children: [
Expanded(
child: Container(
child: WillPopScope(
onWillPop: () async => !await keyOne.currentState.maybePop(),
child: Navigator(
key: keyOne,
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(
builder: (context) => ScreenOne(),
);
},
),
),
),
),
Expanded(
child: Container(
child: WillPopScope(
onWillPop: () async => !await keyTwo.currentState.maybePop(),
child: Navigator(
key: keyTwo,
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(
builder: (context) => ScreenTwo(),
);
},
),
),
),
),
],
);