Okhellohey
Okhellohey

Reputation: 55

Switching pages in flutter

I have a side menu created using a Drawer Widget and I want to navigate between the pages in the side menu. I am using Navigator.push() to do so, but for some reason, the page won't change.

The items appear in the side menu, but when clicked on, the page remains the same. Does anyone know how I am misusing Navigator.push()?

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

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

class MyApp extends StatelessWidget {
  @override 
  Widget build(BuildContext context){
    return MaterialApp(
      title: 'Grid App',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Grip App'),
        ),
        body: Center(
          child: Text('Hello, this is the start page!'),
        ),
        drawer: Drawer(
          child: ListView(
            children: <Widget>[
              DrawerHeader(
                child: Text("Navigation"),
                decoration: BoxDecoration(
                color: Colors.grey[700]
                ),
              ),
              ListTile(
                title: Text("First Page"),
                onTap: (){
                  Navigator.push(
                    context, 
                    MaterialPageRoute(builder: (context) => FirstPage()),);
                },
              ),
              ListTile(
                title: new Text("Second Page"),
                onTap: () {
                  Navigator.push(context,
                    new MaterialPageRoute(builder: (context) => new SecondPage()),);
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class FirstPage extends StatelessWidget{
  @override 
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: Text("First Page"),
      ),
        body: Center(
          child: Text("You're on the first page!"),
        ),
    );
  }
}

class SecondPage extends StatelessWidget{
  @override 
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Page"),
      ),
        body: Text("This is the second page"),
    );
  }
}

Upvotes: 1

Views: 9607

Answers (4)

hamamulfz
hamamulfz

Reputation: 335

Just separate the MaterialApp with another screen. Simply you can right click on the Scaffold widget and select Extract Widget. Give the name to your widget and it will extract your code into another stateless widget.

copy paste this code to dartpad and run it

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override 
  Widget build(BuildContext context){
    return MaterialApp(
      title: 'Grid App',
      home: NewApp(),
    );
  }
}

class NewApp extends StatelessWidget {
  const NewApp({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Grip App'),
      ),
      body: Center(
        child: Text('Hello, this is the start page!'),
      ),
      drawer: Drawer(
        child: ListView(
          children: <Widget>[
            DrawerHeader(
              child: Text("Navigation"),
              decoration: BoxDecoration(
              color: Colors.grey[700]
              ),
            ),
            ListTile(
              title: Text("First Page"),
              onTap: (){
                Navigator.push(
                  context, 
                  MaterialPageRoute(builder: (context) => FirstPage()),);
              },
            ),
            ListTile(
              title: new Text("Second Page"),
              onTap: () {
                Navigator.push(context,
                  new MaterialPageRoute(builder: (context) => new SecondPage()),);
              },
            ),
          ],
        ),
      ),
    );
  }
}

class FirstPage extends StatelessWidget{
  @override 
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: Text("First Page"),
      ),
        body: Center(
          child: Text("You're on the first page!"),
        ),
    );
  }
}

class SecondPage extends StatelessWidget{
  @override 
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Page"),
      ),
        body: Text("This is the second page"),
    );
  }
}

Upvotes: 3

Ravinder Kumar
Ravinder Kumar

Reputation: 8010

Quick Fix

void main() => runApp(MaterialApp(home: MyApp()));

Error You are facing

Your current code gives below error, you can see that in the console too

Error: The following assertion was thrown while handling a gesture: Navigator operation requested with a context that does not include a Navigator. The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.


You can solve this by taking MaterialApp or Builder

Upvotes: 0

duongdt3
duongdt3

Reputation: 1678

Big problem here is using wrong context.

You can't use App context for Navigator. Take a try with Builder

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Grid App',
      home: Builder(
        builder: (context) => buildScaffold(context),
      ),
    );
  }

  Scaffold buildScaffold(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Grip App'),
      ),
      body: Center(
        child: Text('Hello, this is the start page!'),
      ),
      drawer: Drawer(
        child: ListView(
          children: <Widget>[
            DrawerHeader(
              child: Text("Navigation"),
              decoration: BoxDecoration(color: Colors.grey[700]),
            ),
            ListTile(
              title: Text("First Page"),
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => FirstPage()),
                );
              },
            ),
            ListTile(
              title: new Text("Second Page"),
              onTap: () {
                Navigator.push(
                  context,
                  new MaterialPageRoute(builder: (context) => new SecondPage()),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

Upvotes: 0

Anil Chauhan
Anil Chauhan

Reputation: 716

The Navigator won't work if you're doing in under the MateriaApp context like you are using. Remove MaterialApp widget to main() or make another Widget for That.

Try this :


import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() => runApp(MaterialApp(
  home: MyApp(),
));

class MyApp extends StatelessWidget {
  @override 
  Widget build(BuildContext context){
    return Scaffold(
        appBar: AppBar(
          title: Text('Grip App'),
        ),
        body: Center(
          child: Text('Hello, this is the start page!'),
        ),
        drawer: Drawer(
          child: ListView(
            children: <Widget>[
              DrawerHeader(
                child: Text("Navigation"),
                decoration: BoxDecoration(
                color: Colors.grey[700]
                ),
              ),
              ListTile(
                title: Text("First Page"),
                onTap: (){
                  Navigator.push(
                    context, 
                    MaterialPageRoute(builder: (context) => FirstPage()),);
                },
              ),
              ListTile(
                title: new Text("Second Page"),
                onTap: () {
                  Navigator.push(context,
                    new MaterialPageRoute(builder: (context) => new SecondPage()),);
                },
              ),
            ],
          ),
        ),
    );
  }
}

class FirstPage extends StatelessWidget{
  @override 
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: Text("First Page"),
      ),
        body: Center(
          child: Text("You're on the first page!"),
        ),
    );
  }
}

class SecondPage extends StatelessWidget{
  @override 
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Page"),
      ),
        body: Text("This is the second page"),
    );
  }
}

Upvotes: 0

Related Questions