来自MaterialApp构建器的导航器

时间:2019-10-09 16:42:09

标签: flutter dart

我正在尝试将我的整个应用程序嵌入到AppBar和页脚中。 因此,我尝试为我的MaterialApp提供一个自定义的Builder,它看起来像这样(为了清楚起见,我用一个按钮替换了页脚和应用栏)

import 'package:epicture/scenes/Landing.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      initialRoute: '/',
      builder: (context, child) => Container(
          child: FlatButton(
                child: Text('Click me'),
                onPressed: () => Navigator.of(context).pushNamed('/app'),
      )),
      // In my current code
      builder: (context, child) => Embedder(child),
      routes: <String, WidgetBuilder>{
        '/': (context) => Landing(),
        '/app': (context) => Text('My App !'),
      },
    );
  }
}

但是在按下“点击我”按钮时,会出现一个错误,提示上下文没有导航器

the context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget

但是实际上,该按钮是一个页脚,可以单击该页脚来更改每个页面的页面。

我想知道如何从自定义构建器访问导航器,以及是否只是想以错误的方式在应用程序的每个页面(页脚和标头)中使用相同的模式

2 个答案:

答案 0 :(得分:2)

您无法从Navigator内部用context访问builder,因为此builder返回的任何小部件都是导航器的父级。

那我该怎么办?我可以在这里访问导航器吗?

是的!您可以创建一个GlobalKey并将其传递给您的MaterialApp。然后使用该密钥访问Navigator内部的builder

示例:

import 'package:epicture/scenes/Landing.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  final GlobalKey<NavigatorState> _navigator = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      initialRoute: '/',
      navigatorKey: _navigator,
      builder: (context, child) {
        return Container(
          child: FlatButton(
            child: Text('Click me'),
            onPressed: () => _navigator.currentState.pushNamed('/app'),
          ),
        );
      },
      routes: <String, WidgetBuilder>{
        '/': (context) => Landing(),
        '/app': (context) => Text('My App !'),
      },
    );
  }
}

希望有帮助!

答案 1 :(得分:0)

将此上下文变量重命名为

builder: (context, child)

对于此处使用的上下文,您会遇到名称冲突:

onPressed: () => Navigator.of(context).pushNamed('/app'),