实际导航的颤动导航抽屉

时间:2018-05-29 09:20:18

标签: navigation flutter scaffold

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:1)

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

这是我找到示例的文章。

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

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