How can I get the Navigator to work in Flutter?

Issue

I’m new on Flutter, so obviously I’m messing up somewhere in the code that I’m not being able to figure out. Basically I have a login screen from which I want to navigate to a second screen, but when I select the button absolutely nothing happens, nor does an error appear. I have been looking all over for an answer but none of them can solve the problem. I hope someone can help me. (The texts of the buttons are in Spanish).

This is the main.dart:

import 'package:flutter/material.dart';

import 'package:go_out/screens/screens.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      initialRoute: 'home',
      routes: {
        'home': (_) => const HomeScreen(),
        'signInEmail': (_) => const SignInEmail(),
      },
    );
  }
}

This is the home_screen.dart:

import 'package:flutter/material.dart';

import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../widgets/widgets.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      backgroundColor: Colors.black,
      body: Padding(
        padding: EdgeInsets.only(left: 15, right: 15),
        child: Center(
          child: _SignInPageDesign(),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(left: 10, right: 10),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Image.asset(
            'images/logo.png',
            height: 200,
            fit: BoxFit.cover,
          ),
          const SizedBox(
            height: 30,
          ),
          CustomElevatedButtonWithoutIcon(
            text: 'Crear Cuenta',
            onPressed: () => Navigator.pushNamed(context, 'signInEmail'),
          ),
          const SizedBox(height: 12),
          CustomElevatedButtonWithIcon(
            text: 'Continuar con Facebook',
            onPressed: () {},
            icon: FontAwesomeIcons.facebookSquare,
          ),
          const SizedBox(height: 12),
          CustomElevatedButtonWithIcon(
            text: 'Continuar con Google',
            onPressed: () {},
            icon: FontAwesomeIcons.google,
          ),
          const SizedBox(height: 12),
          CustomElevatedButtonWithIcon(
            text: 'Continuar con Apple',
            onPressed: () {},
            icon: FontAwesomeIcons.apple,
          ),
          const SizedBox(height: 12),
          const CustomTextButton(
            text: 'Iniciar sesiĆ³n',
          ),
          const SizedBox(height: 12),
          CustomElevatedButtonWithoutIcon(
            text: 'Registrar comercio',
            onPressed: () {},
          ),
        ],
      ),
    );
  }
}

This is the problem with home_screen.dart which does not return any value.

CustomElevatedButtonWithoutIcon(
            text: 'Crear Cuenta',
            onPressed: () => Navigator.pushNamed(context, 'signInEmail'),
          ),

This is the second screen I want to go to sign_in_email.dart:

import 'package:flutter/material.dart';

class SignInEmail extends StatelessWidget {
  const SignInEmail({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: const Color.fromRGBO(254, 80, 0, 1),
      ),
    );
  }
}

This is the class CustomElevatedButtonWithoutIcon:

import 'package:flutter/material.dart';

class CustomElevatedButtonWithoutIcon extends StatelessWidget {
  const CustomElevatedButtonWithoutIcon({
    Key? key,
    required this.text,
    required this.onPressed,
  }) : super(key: key);
  final String text;
  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      child: Text(
        text,
        style:
            const TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
      ),
      onPressed: () {},
      style: ButtonStyle(
        fixedSize: MaterialStateProperty.all<Size>(const Size(0, 50)),
        backgroundColor: MaterialStateProperty.all<Color>(
            const Color.fromRGBO(254, 80, 0, 1)),
        shape: MaterialStateProperty.all<RoundedRectangleBorder>(
          RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20.0),
          ),
        ),
      ),
    );
  }
}

Solution

You didn’t pass anything onPressed funciton, you kept it empty, so nothing was working, just pass your onPressed function inside ElevatedButton like below

import 'package:flutter/material.dart';

class CustomElevatedButtonWithoutIcon extends StatelessWidget {
  const CustomElevatedButtonWithoutIcon({
    Key? key,
    required this.text,
    required this.onPressed,
  }) : super(key: key);
  final String text;
  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      child: Text(
        text,
        style:
            const TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
      ),
      onPressed: onPressed,
      style: ButtonStyle(
        fixedSize: MaterialStateProperty.all<Size>(const Size(0, 50)),
        backgroundColor: MaterialStateProperty.all<Color>(
            const Color.fromRGBO(254, 80, 0, 1)),
        shape: MaterialStateProperty.all<RoundedRectangleBorder>(
          RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20.0),
          ),
        ),
      ),
    );
  }
}

Also it’s best practice to use RouteGenerator, create a route_generator.dart file with the following code below

import 'package:flutter/material.dart';

class RouterCustom {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    final args = settings.arguments;

    switch (settings.name) {
      case "home":
        return MaterialPageRoute(
          builder: (_) => const HomeScreen(),
          settings: const RouteSettings(name: "home"),
        );
      case "signInEmail":
        return MaterialPageRoute(
          builder: (_) => const SignInEmail(),
          settings: const RouteSettings(name: "signInEmail"),
        );

      default:
        return MaterialPageRoute(
          builder: (_) => Scaffold(
            body: Center(
              child: Text('No route defined for ${settings.name}'),
            ),
          ),
          settings: const RouteSettings(name: "404"),
        );
    }
  }
}

Then pass it to your main method’s router param

MaterialApp(
  initialRoute: "home",
  onGenerateRoute: RouterCustom.generateRoute,
)

Answered By – Rafat Rashid Rahi

Answer Checked By – Willingham (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *