【问题标题】:Child page is retaining AppBar and BottomNavigationBar子页面保留 AppBar 和 BottomNavigationBar
【发布时间】:2020-07-09 22:13:40
【问题描述】:

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

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

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),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),);
  }
}

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案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(),
    

    【讨论】:

    • 你的意思是每个页面的 Scaffold Widget 吗?只是重复使用它们?
    • 我认为他的意思是像构建身体一样接近构建 appBar。某个索引定义了构建哪个主体,因此它可以定义您的 appBar 是否以及如何构建
    猜你喜欢
    • 2019-11-13
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    • 2019-07-01
    相关资源
    最近更新 更多