首页 文章

实际导航的颤动导航抽屉

提问于
浏览
3

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

我找到的大多数方法(like this)只使用有状态小部件并在轻敲抽屉项目时更改其状态 .

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

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

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

这似乎是一个常见的问题(例如,所有谷歌应用程序都这样工作),我对如何正确实现这一点感到困惑 . 自定义导航器是正确的方法吗?有一些例子吗?

2 回答

  • 0

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

    这是我找到一个例子的文章 .

    [https://proandroiddev.com/flutter-creating-drawers-e31414f7d71a][1]

  • -1

    我不知道天气是不是这样做的正确方法,但这是我做这件事的最佳方式 . 试试看 .

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

相关问题