Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Navigator Pop does not work

I have found flutter yesterday and have tried around a bit, though I have one problem. I have followed a tutorial to implement a Navigation Drawer (this one) and the drawer opens nice and all and the buttons change what they should change BUT the call to Navigator.pop(context) or Navigator.of(context).pop() (both) behaves like this:

Before tap on "Characters"

Before tap

After tap on "Characters"

After tap

I have searched around the web but I couldn't find anyone with the same issue :/ Here's my code:

main.dart:

import 'package:flutter/material.dart';
import 'package:dnd/home.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'DnD',
        home: new Home()
    );
  }
}

home.dart:

import 'package:flutter/material.dart';
import 'package:dnd/home_fragment.dart';
import 'package:dnd/char_fragment.dart';

class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new HomeState();
  }
}

class HomeState extends State<Home> {
  int selectedDrawerIndex = 0;

  getDrawerItemWidget(int pos) {
    switch(pos) {
      case 0:
        return new HomeFragment();
      case 1:
        return new CharFragment();

      default:
        return new Text('ERROR');
    }
  }

  onSelectItem(int index) {
    setState(() => selectedDrawerIndex = index);
    print(Navigator.of(context).pop());
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'DnD',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text(
            'DnD'
          )
        ),
        drawer: new Drawer(
          child: new Column(
            children: <Widget>[
              new UserAccountsDrawerHeader(
                accountName: new Text(
                  'bla'
                ),
                accountEmail: null,
              ),
              new Column(
                children: <Widget>[
                  new ListTile(
                    title: new Text(
                      'Home'
                    ),
                    leading: new Icon(
                      Icons.home
                    ),
                    selected: 0 == selectedDrawerIndex,
                    onTap: () => onSelectItem(0),
                  ),
                  new ListTile(
                    title: new Text(
                      'Characters'
                    ),
                    leading: new Icon(
                      Icons.person
                    ),
                    selected: 1 == selectedDrawerIndex,
                    onTap: () => onSelectItem(1),
                  )
                ],
              ),
            ],
          ),
        ),
        body: getDrawerItemWidget(selectedDrawerIndex)
      )
    );
  }
}

home_fragment.dart:

import 'package:flutter/material.dart';

class HomeFragment extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Center(
      child: new Text(
        'moin'
      )
    );
  }
}

char_fragment.dart:

import 'package:flutter/material.dart';

class CharFragment extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
      return new CharState();
    }
}

class CharState extends State<CharFragment> {
  characterNew() async {
    await showDialog<bool>(
      context: context,
      child: new AlertDialog(
        title: new Text('Create new Character?'),
        actions: <Widget>[
          new FlatButton(
            child: new Text('Yes'),
            onPressed: () => Navigator.of(context).pop(true)
          ),
          new FlatButton(
            child: new Text('No'),
            onPressed: () => Navigator.of(context).pop(false)
          )
        ],
      )
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Center(
      child: new GridView.count(
        crossAxisCount: 3,
        crossAxisSpacing: 10.0,
        mainAxisSpacing: 10.0,
        children: <Widget>[
          new RaisedButton.icon(
            onPressed: characterNew,
            icon: new Icon(Icons.add, size: 80.0,),
            label: new Text('')
          )
        ],
      )
    );
  }
}
like image 551
schnavid Avatar asked Apr 07 '18 12:04

schnavid


2 Answers

There are two things that are wrong in your code:

  1. You are using MaterialApp twice, you should only have one instance of MaterialApp as it holds your root configuration.
  2. You are not pushing any route on the Navigator stack, so you are trying to pop from an empty list (ie, there is nothing inside the stack to be popped).

To demonstrate, you are controlling the content of the Scaffold body by using setState so you are switching between Home and Charaters widgets and they really can not see each other (if you choose Home widget, your Char widget is not built, now if you choose your Char widget, your Home widget has been fully replaced by it)

like image 107
Shady Aziza Avatar answered Nov 07 '22 10:11

Shady Aziza


In the home.dart Build override. Try to return a Scaffold instead of another instance of Material app. You now return a Material app in the body of the material app. You should return just the Scaffold there.

like image 32
Kevin Walter Avatar answered Nov 07 '22 10:11

Kevin Walter