子页面保留AppBar和BottomNavigationBar

时间:2020-03-29 14:09:02

标签: flutter flutter-layout

我是新来的,它在导航中挣扎了几个小时。在下图中,在第2页上,我们有AppBar,body和BottomNavigationBar,它们都在工作。

enter image description here

问题是当我点击“转到其他页面”时,我想要一个没有以前的AppBar和BottomNavigationBar的完整页面。但是我得到了

enter image description here

MyApp的代码在下面

class NavApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Navigation App',
      home: NavAppPlaceholder(),
    );
  }
}

class NavAppPlaceholder extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _NavAppPlaceholderState();
}

class _NavAppPlaceholderState extends State<NavAppPlaceholder> {
  final _navigatorKey = GlobalKey<NavigatorState>();
  List<String> routes = ['/', '/page1', '/page2'];
  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
    _navigatorKey.currentState.pushNamed(routes.elementAt(index));
  }

  int _selectedIndex = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Main App'),),
      body: WillPopScope(
        child: Navigator(
          initialRoute: '/',
          key: _navigatorKey,
          onGenerateRoute: (RouteSettings settings) {
            WidgetBuilder builder;
            switch (settings.name) {
              case '/':
                builder = (BuildContext context) => HomePage();
                break;
              case '/page1':
                builder = (BuildContext context) => Page1();
                break;
              case '/page2':
                builder = (BuildContext context) => Page2();
                break;
              case '/otherpage':
                builder = (BuildContext context) => OtherPage();
                break;
              default:
                throw Exception('Invalid route: ${settings.name}');
            }
            return MaterialPageRoute(
              builder: builder,
              settings: settings,
            );
          },
        ),
        onWillPop: () async {
          if (_navigatorKey.currentState.canPop()) {
            _navigatorKey.currentState.pop();
            return false;
          }
          return true;
        },
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
          BottomNavigationBarItem(
              icon: Icon(Icons.pageview), title: Text('Page 1')),
          BottomNavigationBarItem(
              icon: Icon(Icons.description), title: Text('Page 2')),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
        type: BottomNavigationBarType.fixed,
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text('Home page...!'));
  }
}

class Page1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text('Page 1...!'));
  }
}

class Page2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(child: FlatButton(onPressed: (){
      Navigator.pushNamed(context, '/otherpage');
    }, child: Text('Go to other page')));
  }
}
class OtherPage extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Other Page')),
      body:  SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Expanded(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  Expanded(
                    child: Container(
                      color: Colors.red,
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.start,
                        children: <Widget>[
                          Text('Left', textAlign: TextAlign.center),
                          Text('Left', textAlign: TextAlign.center),
                          Text('Left', textAlign: TextAlign.center),
                        ],
                      ),
                    ),
                  ),
                  Expanded(
                    child: Container(
                      color: Colors.green,
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.end,
                        children: <Widget>[
                          Text('Right', textAlign: TextAlign.center),
                          Text('Right', textAlign: TextAlign.center),
                          Text('Right', textAlign: TextAlign.center),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
            Expanded(
              child: Container(
                color: Colors.blue,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text('Bottom', textAlign: TextAlign.center),
                    Text('Bottom', textAlign: TextAlign.center),
                    Text('Bottom', textAlign: TextAlign.center),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),);
  }
}

1 个答案:

答案 0 :(得分:1)

这是因为您正在使用

_navigatorKey.currentState.pushNamed(routes.elementAt(index));

推到另一个屏幕。通过使用Global NavigatorState,您将保留父页面中已经存在的内容,即AppBar和BottomNavigationBar。

除了使用Global NavigatorState之外,另一种方法是创建一个不同的类来存储AppBar和BottomNavigationBar,这些类可以被其他页面调用。

创建一个名为bottomBar.dart的新文件,它将返回此文件

return BottomNavigationBar(
  items: const <BottomNavigationBarItem>[
    BottomNavigationBarItem(
      icon: Icon(Icons.home),
      title: Text('Home'),
    ),
    BottomNavigationBarItem(
        icon: Icon(Icons.pageview),
        title: Text('Page 1')
    ),
    BottomNavigationBarItem(
        icon: Icon(Icons.description),
        title: Text('Page 2')
    ),
  ],
  currentIndex: _selectedIndex,
  selectedItemColor: Colors.amber[800],
  onTap: _onItemTapped,
  type: BottomNavigationBarType.fixed,
);

然后在main.dart中使用此

bottomNavigationBar: CustomBottomBar(),