【问题标题】:Flutter Navigation Drawer that actually navigates实际导航的 Flutter Navigation Drawer
【发布时间】:2018-11-07 21:26:33
【问题描述】:

我有一个简单的Scaffold,有一个抽屉和一个身体。我想在抽屉中选择一个项目并让脚手架的主体导航到一个新视图。

我发现的大多数方法 (like this) 只是使用有状态小部件并在点击抽屉项目时更改其状态。

但是,这完全忽略了应用的导航堆栈,并且按返回不会按预期返回到上一个视图。

另一方面,在单击项目时使用 Navigator.of(context).push... 会使用导航堆栈,但会更改整个屏幕,这也不是我想要的。

我尝试为脚手架的主体创建一个新的自定义导航器,但在从抽屉中访问 NavigatorState 时遇到问题。

这对我来说似乎是一个常见问题(例如,所有谷歌应用程序都以这种方式工作),我对如何正确实现这一点有点困惑。 自定义导航器是正确的方法吗?有没有可用的例子?

【问题讨论】:

  • 您是否尝试使用其他正常的导航栏功能在同一页面中显示不同的内容?
  • 我只想改变脚手架主体,它周围的所有东西(尤其是抽屉)都应该保持不变。目前没有其他导航

标签: navigation flutter scaffold


【解决方案1】:

您似乎只需要为抽屉创建一个 Widget,并将其包含在应用程序每个屏幕的 Scaffold 中。这样您就可以使用 Navigator 来保留导航堆栈,并仅在您决定的屏幕中包含抽屉。

This is the article 我在这里找到了一个例子。

【讨论】:

    【解决方案2】:

    我不知道这样做是否正确,但这是迄今为止我最好的方法。试试看吧。

    import 'dart:async';
    import 'package:flutter/material.dart';
    
    void main() => runApp(new MaterialApp(debugShowCheckedModeBanner: false, home: new HomePage(),),);
    
    class HomePage extends StatefulWidget {
      @override
      _HomePageState createState() => new _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      Widget currentPage;
    
      @override
      void initState() {
        super.initState();
    
        if(currentPage == null || _recentPages.length == 0)
          currentPage = new PageOne();
      }
    
      @override
      Widget build(BuildContext context) {
        return new WillPopScope( // To process back pressed event
          onWillPop: onWillPop,
          child: new Scaffold(
            appBar: new AppBar(title: new Text('Home'),),
            drawer: new Drawer(
              child: new ListView(
                children: <Widget>[
                  new DrawerHeader(
                    child: new UserAccountsDrawerHeader(
                      accountName: new Text('Vinoth Kumar'),
                      accountEmail: new Text('vinoth1094@gmail.com'),
                      currentAccountPicture: new CircleAvatar(
                          backgroundImage: new NetworkImage(
                              'https://scontent.fmaa1-1.fna.fbcdn.net/v/t1.0-9/16196015_10154888128487744_6901111466535510271_n.png?_nc_cat=0&oh=b987a0608ad9dad1beff57c489e53221&oe=5BB865E9')),
                    ),
                    padding: const EdgeInsets.all(0.0),
                    margin: const EdgeInsets.all(0.0),
                  ),
                ]..addAll(_buildNavigationItems()),
              ),
            ),
            body: currentPage,
          ),
        );
      }
    
      List<Widget> _buildNavigationItems() {
        List<Widget> navList = [];
        for (int i=0; i<_navigationItems.length; i++) {
          navList.add(new ListTile(
            title: new Text(_navigationItems[i].name),
            trailing: new Icon(_navigationItems[i].icon),
            onTap: () {
              onNavigationIconClicked(i);
            },
          ));
        }
        return navList;
      }
    
      onNavigationIconClicked(int i) {
        switch(_navigationItems[i].name) {
          case 'Page 1':
            if (!(currentPage is PageOne)) {
              Navigator.of(context).pop();
              setState(() {
                _recentPages.add(currentPage); // Add current page to _recentPages
                currentPage = new PageOne(); // Show new page
              });
            }
            break;
          case 'Page 2':
            if (!(currentPage is PageTwo)) {
              Navigator.of(context).pop();
              setState(() {
                _recentPages.add(currentPage); // Add current page to _recentPages
                currentPage = new PageTwo(); // Show new page
              });
            }
            break;
          case 'Page 3':
            if (!(currentPage is PageThree)) {
              Navigator.of(context).pop();
              setState(() {
                _recentPages.add(currentPage); // Add current page to _recentPages
                currentPage = new PageThree(); // Show new page
              });
            }
            break;
          case 'Page 4':
            if (!(currentPage is PageFour)) {
              Navigator.of(context).pop();
              setState(() {
                _recentPages.add(currentPage); // Add current page to _recentPages
                currentPage = new PageFour(); // Show new page
              });
            }
            break;
        }
      }
    
      Future<bool> onWillPop() async{
        if (_recentPages.length == 0) {
          return true;
        } else {
          setState(() {
            currentPage = _recentPages[_recentPages.length - 1];
            _recentPages.removeLast();
          });
          return false;
        }
      }
    }
    
    List<Widget> _recentPages = [];
    
    List<NavigationItem> _navigationItems = [
      new NavigationItem('Page 1', Icons.keyboard_arrow_right),
      new NavigationItem('Page 2', Icons.keyboard_arrow_right),
      new NavigationItem('Page 3', Icons.keyboard_arrow_right),
      new NavigationItem('Page 4', Icons.keyboard_arrow_right),
    ];
    
    class NavigationItem {
      final String name;
      final IconData icon;
    
      NavigationItem(this.name, this.icon);
    }
    

    示例页面:

    class PageOne extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: new Text('Page One'),
        );
      }
    }
    
    class PageTwo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: new Text('Page Two'),
        );
      }
    }
    
    class PageThree extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: new Text('Page Three'),
        );
      }
    }
    
    class PageFour extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: new Text('Page Four'),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-27
      • 2019-08-01
      • 2021-01-01
      • 1970-01-01
      • 2021-01-25
      • 1970-01-01
      相关资源
      最近更新 更多