Home > Enterprise >  NavigatorPush is not working on my Flutter App
NavigatorPush is not working on my Flutter App

Time:07-06

I try to build simple login with laravel but then got stuck. After login success I can't redirect to another page with Navigator.push. I think I've followed the tutorial right.

this is login.dart

class LoginScreen extends StatefulWidget {
  static const routeName = '/login-screen';
  const LoginScreen({Key? key}) : super(key: key);

  @override
  _LoginScreenState createState() => _LoginScreenState();
}


class _LoginScreenState extends State<LoginScreen> {
  TextEditingController txtUsername = new TextEditingController();
  TextEditingController txtPassword = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size; //provide total height and width
    return Scaffold(
      body: Background(
        child1: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Positioned(
                top: 0,
                left: 0,
                child: Image.asset('assets/images/wedding.png', width: 250),
              ),
              SizedBox(height: size.height * 0.01),
              roundedInputField(
                hintText: 'Email',
                controller: txtUsername,
                onChanged: (value) {},
              ),
              PasswordField(
                hintText: 'Password',
                controller: txtPassword,
                onChanged: (value) {},
              ),
              Button(
                text: 'LOGIN',
                press: () {
                  this.doLogin();
                },
              )
            ],
          ),
        ),
      ),
    );
  }


  void showToast(msg) => Fluttertoast.showToast(msg: msg);

  Future doLogin() async {
    WidgetsBinding.instance.focusManager.primaryFocus?.unfocus();
    if(txtUsername.text.isEmpty || txtPassword.text.isEmpty) {
      showToast('email/password kosong');
    }else {
      showDialog(
          context: context,
          builder: (context) {
            return Center(
              child: CircularProgressIndicator(),
            );
          });

      final response = await http.post(
          Uri.parse('http://10.0.2.2/flutter/api/login'),
          body: {'email': txtUsername.text, 'password': txtPassword.text},
          headers: {'Accept': 'application/json'}
      );
      final responseData = json.decode(response.body);

      if (response.statusCode == 200) {
        showToast('berhasil login');
         Navigator.push(
             context,
             MaterialPageRoute(
               builder: (BuildContext context) => const NavbarScreen(),
             ));
        // Navigator.of(context).push(
        //  MaterialPageRoute(builder: (_){
        //      return NavbarScreen();
        //    },
        //  ),
        // );
        //print(responseData);
      } else {
        showToast('gagal login');
      }
      Navigator.of(context).pop(); //end loading
    }
  }



}

This is the login logic in login.dart

if (response.statusCode == 200) {
    showToast('berhasil login');
    Navigator.push(
        context,
        MaterialPageRoute(
          builder: (BuildContext context) => const NavbarScreen(),
        ));
    //print(responseData);
  } else {
    showToast('gagal login');
  }

This is main.dart

void main() {
  runApp(const MyApp());
}

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


  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Breeze',
      theme: ThemeData(
        primaryColor: kPrimaryColor,
        scaffoldBackgroundColor: Colors.white,
      ),
      //home: DashboardScreen(),
      initialRoute: '/',
      routes: {
        '/': (ctx) => LoginScreen(),
        LoginScreen.routeName: (ctx) => LoginScreen(),
        NavbarScreen.routeName: (ctx) => NavbarScreen(),
        CheckinScreen.routeName: (ctx) => CheckinScreen(),
        CheckoutScreen.routeName: (ctx) => CheckoutScreen(),
      },
    );
  }
}

CodePudding user response:

try using named route navigator. I show how to route with or without parameters. The generator class contains all the routing definitions in one place

class MyApp extends StatelessWidget{
      return MaterialApp(
       ...
       onGenerateRoute: RouteGenerator.handleRoute,
       ...
    }
Navigator.pushNamed(context, RouteGenerator.homePage);


Navigator.pushNamed(
                                    context, 
RouteGenerator.page2Page,
                                    arguments: myView)
                                .then((completion) {
                              });

class RouteGenerator {
  static const String homePage = "/home";
  static const String page1Page = "/page1";
  static const String page2Page = "/page2";

  RouteGenerator._();
  static Route<dynamic> handleRoute(RouteSettings routeSettings) {
    Widget childWidget;
    switch (routeSettings.name) {
      case homePage:
        {
          childWidget = HomePageWidget(title: 'Home');
        }
        break;
      case page1Page:
        {
          childWidget = Page1Widget();
        }
        break;
      case page2Page:
        {
          final args = routeSettings.arguments as MyView;
          childWidget = Page2Widget(args);
        }
        break;
      default:
        throw FormatException("Route Not Found");
    }
    return MaterialPageRoute(builder: (context) => childWidget);
  }
}

CodePudding user response:

Firstly, you are using two different routename for LoginScreen. While this will be the home use

 static const routeName = '/';

Now for the method try passing context for safety doLogin(context)

showDialog, push and Fluttertoast.showToast are future methods, provide await before theses.

  Future<void> showToast(msg) async => await Fluttertoast.showToast(msg: msg);

showDialog brings another context that is needed to be close to move further. Hopping you are just depending on barrierDismissible: true. else create button or logic to close the dialog.

 Future<void> doLogin(BuildContext context) async {
    await showDialog(
      context: context,
      barrierDismissible: true,
      builder: (context) {
        return Center(
          child: Column(
            children: [
              Center(
                child: CircularProgressIndicator(),
              ),
              ElevatedButton(
                  onPressed: Navigator.of(context).pop,
                  child: Text("Close the dialog"))
            ],
          ),
        );
      },
    );

    await showToast('berhasil login');
    await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (BuildContext context) => TS(), // place your screen widget
        ));
  }

CodePudding user response:

@Damara Jati P Kindly make the following changes Step 1-3

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class LoginScreen extends StatefulWidget {
  static const routeName = '/login-screen';
  const LoginScreen({Key? key}) : super(key: key);

  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  TextEditingController txtUsername = new TextEditingController();
  TextEditingController txtPassword = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size; //provide total height and width
    return Scaffold(
      body: Background(
        child1: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Positioned(
                top: 0,
                left: 0,
                child: Image.asset('assets/images/wedding.png', width: 250),
              ),
              SizedBox(height: size.height * 0.01),
              roundedInputField(
                hintText: 'Email',
                controller: txtUsername,
                onChanged: (value) {},
              ),
              PasswordField(
                hintText: 'Password',
                controller: txtPassword,
                onChanged: (value) {},
              ),
              Button(
                text: 'LOGIN',
                press: () {
                  // Steps 1 
                  this.doLogin(context);
                },
              )
            ],
          ),
        ),
      ),
    );
  }

  void showToast(msg) => Fluttertoast.showToast(msg: msg);

  // Steps 2 
  Future doLogin(BuildContext context) async {
    WidgetsBinding.instance.focusManager.primaryFocus?.unfocus();
    if (txtUsername.text.isEmpty || txtPassword.text.isEmpty) {
      showToast('email/password kosong');
    } else {
      showDialog(
          context: context,
          builder: (context) {
            return Center(
              child: CircularProgressIndicator(),
            );
          });

      final response = await http.post(
          Uri.parse('http://10.0.2.2/flutter/api/login'),
          body: {'email': txtUsername.text, 'password': txtPassword.text},
          headers: {'Accept': 'application/json'});
      final responseData = json.decode(response.body);

      if (response.statusCode == 200) {
        showToast('berhasil login');

        // Steps 3
        Navigator.push(
            context, MaterialPageRoute(builder: (context) => NavbarScreen()));
      } else {
        showToast('gagal login');
      }
    }
  }
}
  • Related