Flutter Navigation Drawer, который фактически перемещается - PullRequest
0 голосов
/ 29 мая 2018

У меня есть простой Scaffold с ящиком и телом.Я хочу выбрать элемент в выдвижном ящике и переместить тело эшафота в новое представление.

Большинство найденных мною подходов ( как этот ) просто используют виджет с сохранением состояния и меняют его состояниепри касании элемента ящика.

Однако это полностью игнорирует стек навигации приложения, и нажатие назад не возвращает к предыдущему виду, как ожидалось.

С другой стороны, используя Navigator.of(context).push... при нажатии элемента использует стек навигации, но изменяет весь экран, что тоже не то, что мне нужно.

Я попытался создать новый пользовательский навигатор для тела лесов, но возникли проблемы с доступом кNavigatorState из ящика.

Мне кажется, это общая проблема (например, все приложения Google работают так), и я немного запутался, как правильно это реализовать.Является ли пользовательский навигатор правильным подходом?Есть ли примеры, доступные?

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Похоже, вам нужно создать виджет только для ящика и включить его в эшафот каждого экрана вашего приложения.Таким образом, вы можете использовать Навигатор, сохраняющий стек навигации, и включать ящик только в те экраны, которые вы решите.

Это статья , где я нашел пример.

0 голосов
/ 29 мая 2018

Я не знаю, погода это правильный способ сделать это или нет, но это лучший способ для меня это сделать.Попробуйте.

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