我一直在四处寻找一个很好的Ffltter导航/路由示例,但没有找到.

我想要实现的很简单:

  1. 突出显示当前顶层路由的持久底部导航栏
  2. 命名路由,以便我可以从应用程序内的任何位置导航到任何路由
  3. Navigator.op应该始终将我带到我所处的上一个视图

BottomNavigationBar的官方Flutter 演示实现了1,但是后退按钮和路由不起作用.PageView和TabView也有同样的问题.还有许多其他教程通过实现MaterialApp routes来实现2和3,但似乎没有一个有持久的导航栏.

有没有能满足所有这些要求的导航系统的例子?

推荐答案

您的所有3个要求都可以通过使用定制的Navigator来实现.

弗利特团队对此做了video分,他们关注的文章如下:https://medium.com/flutter/getting-to-the-bottom-of-navigation-in-flutter-b3e440b9386

基本上,你需要用一个定制的Navigator:

class _MainScreenState extends State<MainScreen> {
  final _navigatorKey = GlobalKey<NavigatorState>();

  // ...

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Navigator(
        key: _navigatorKey,
        initialRoute: '/',
        onGenerateRoute: (RouteSettings settings) {
          WidgetBuilder builder;
          // Manage your route names here
          switch (settings.name) {
            case '/':
              builder = (BuildContext context) => HomePage();
              break;
            case '/page1':
              builder = (BuildContext context) => Page1();
              break;
            case '/page2':
              builder = (BuildContext context) => Page2();
              break;
            default:
              throw Exception('Invalid route: ${settings.name}');
          }
          // You can also return a PageRouteBuilder and
          // define custom transitions between pages
          return MaterialPageRoute(
            builder: builder,
            settings: settings,
          );
        },
      ),
      bottomNavigationBar: _yourBottomNavigationBar,
    );
  }
}

在底部导航栏中,要在新的custom Navigator中导航到新屏幕,只需调用以下命令:

_navigatorKey.currentState.pushNamed('/yourRouteName');

要实现第3个要求,即Navigator.pop,将您带到上一个视图,您将需要用WillPopScope包装自定义Navigator:

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: WillPopScope(
      onWillPop: () async {
        if (_navigatorKey.currentState.canPop()) {
          _navigatorKey.currentState.pop();
          return false;
        }
        return true;
      },
      child: Navigator(
        // ...
      ),
    ),
    bottomNavigationBar: _yourBottomNavigationBar,
  );
}

应该就是这样了!无需手动处理POP或管理自定义历史记录列表.

Flutter相关问答推荐

在创建肘部并使用冻结时,无法使用中的Copy With方法

无效参数(S):隔离消息中的非法参数:try 旋转图像时对象不可发送

flutter -当使用SingleChildScrollView包装我的列小部件时,它不会填充整个高度

将图标呈现在Flutter 克牌小工具的角落上

无法构建AndroidBundle 包或iOS等

参数类型';List<;Dynamic&>不能分配给参数类型';List<;SingleChildWidget&>';

Flutter GestureDetector单击问题-堆叠外面的按钮不可点击

如何在Dart中允许正则表达式中有一个空格,但允许其他字符为1或更多?

打开键盘时屏幕组件会被压扁

SliverAppbar 呈蓝色

Flutter:我应该使用哪种应用内购买服务?

用户文档 ID 与 Firestore 中的用户 ID 相同

如何将此文本按钮剪辑在堆栈中的圆形头像上方?

如何更改 DropDownMenu 的显示方向?

无法使用 bloc 更新 ListView.builder 的特定时间

在提供程序包更改通知程序中构建倒计时时钟

statefulWidget 无法进行所需更改的问题

Flutter Web App 未启动:脚本的 MIME 类型不受支持

Flutter 使用 listview builder 在全屏时添加列滚动

Firebase.initializeApp();和 FirebaseMessaging.instance.getToken() 抛出 android 本机异常