FLUTTER:- I need to return a widget from a method after Navigator.push() method

0

I have made a login app using Flutter and BLOC architecture. If login becomes success I need to return a widget to the scaffold and also want to navigate to the next screen using Navigator.push().

I have tried following ways:-

  1. Method 1:-
Navigator.push(context,MaterialPageRoute(builder: (context) => DashboardPage()));
return ButtonWidget(); 

But it causes an error that you can not set a widget when shifted to the next screen.

  1. Method 2:-
Future.delayed(
        Duration(days: 1200),
        () => {
              Navigator.push(context,
                  MaterialPageRoute(builder: (context) => DashboardPage())),
            }));
return ButtonWidget(); 

But it causes the code inside the future to run after every 1.2 seconds.

3.Method 3:-

var cancellableCompleter = CancelableCompleter(onCancel:(){print("onCancel");});
    cancellableCompleter.complete(
      //Future.value("future result"));
      Future.delayed(
        Duration(days: 1200),
        () => {
              print("i am here"),
              Navigator.push(context,
                  MaterialPageRoute(builder: (context) => DashboardPage())),
            }));
    cancellableCompleter.operation.value.then((value)=>print(value));
    cancellableCompleter.operation.value.whenComplete(()=>{print("Completed")});
    return ButtonWidget();

But it does not instantiate the Navigator.push() method. Even the "I am here" does not get printed.

I have also tried CancelableOperation but it gives the same error as Method 2.

Full Code

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:sales_app/bloc/bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:async/async.dart';

import 'dashboard_page.dart';

class LoginPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _LoginPageState();
  }
}

class _LoginPageState extends State<LoginPage> {
  String _email;
  String _password;
  LoginBloc bloc = LoginBloc();
  final blue_color = Color(0xff4490E8);
  final formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: BlocProvider(
        builder: (context) => bloc,
        child: Container(
          decoration: BoxDecoration(color: blue_color),
          child: Padding(
            padding: const EdgeInsets.all(20.0),
            child: Form(
              key: formKey,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Text(
                    "Log In",
                    style: TextStyle(color: Colors.white, fontSize: 30),
                  ),
                  SizedBox(
                    height: 50,
                  ),
                  TextFormField(
                      autovalidate: true,
                      style: TextStyle(color: blue_color),
                      onSaved: (email) => {this._email = email},
                      keyboardType: TextInputType.emailAddress,
                      initialValue: "saurav.vidyarthi@connexrm.com",
                      validator: (val) =>
                          RegExp(r"^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
                                  .hasMatch(val)
                              ? null
                              : "Invalid Email",
                      decoration: InputDecoration(
                        filled: true,
                        helperStyle: TextStyle(color: blue_color),
                        labelStyle: TextStyle(color: blue_color),
                        labelText: "Email Id",
                        hintText: "e.g. joe@gmail.com",
                        hintStyle: TextStyle(color: blue_color),
                        prefixIcon: Icon(Icons.email, color: blue_color),
                        fillColor: Colors.white,
                        /*border: OutlineInputBorder(
                            borderSide:
                            BorderSide(color: const Color(0xffffffff)))),*/
                      )),
                  SizedBox(height: 15.0),
                  TextFormField(
                      style: TextStyle(color: blue_color),
                      obscureText: true,
                      autovalidate: true,
                      initialValue: "Saurav@1",
                      onSaved: (password) => {_password = password},
                      validator: (val) => val.length < 6
                          ? "Password must be of at least 6 char."
                          : null,
                      decoration: InputDecoration(
                          filled: true,
                          labelStyle: TextStyle(color: blue_color),
                          hintStyle: TextStyle(color: blue_color),
                          prefixIcon: Icon(Icons.lock, color: blue_color),
                          fillColor: Colors.white,
                          /* border: OutlineInputBorder(
                              borderSide:
                              BorderSide(color: const Color(0xffffffff))),*/
                          labelText: "Password",
                          hintText: "*******")),
                  SizedBox(height: 25.0),
                  BlocBuilder(
                    bloc: bloc,
                    builder:
                        (BuildContext buildContext, LoginState loginState) {
                      print(loginState.toString());
                      if (loginState is InitialLoginState)
                        return _buildInitialState();
                      else if (loginState is LoggingInState)
                        return _buildLoadingState();
                      else if (loginState is LoginSuccessState) {
                        LoginSuccessState state = loginState;
                        return _buildSuccessState(state.user.StatusText);
                      } else {
                        LoginFailedState state = loginState;
                        return _buildFailureState(state.user.StatusText);
                      }
                    },
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  void _onButtonPressed() {
    if (formKey.currentState.validate()) {
      formKey.currentState.save();
      bloc.dispatch(GetUser(_email, _password));
    } else {
      Fluttertoast.showToast(msg: "Please enter a valid email and password");
    }
  }

  Widget _buildInitialState() {
    return RaisedButton(
        onPressed: _onButtonPressed,
        color: Colors.white,
        child: Text(
          "Log In",
          style: TextStyle(color: blue_color),
        ));
  }

  Widget _buildLoadingState() {
    return CircularProgressIndicator(backgroundColor: Colors.white);
  }

  Widget _buildFailureState(message) {
    Fluttertoast.showToast(msg: message);
    return RaisedButton(
        onPressed: _onButtonPressed,
        color: Colors.white,
        child: Text(
          "Log In",
          style: TextStyle(color: blue_color),
        ));
  }

  Widget _buildSuccessState(message) {
    Fluttertoast.showToast(msg: message);
    _setAuthState();
    var cancellableCompleter = CancelableCompleter(onCancel:(){print("onCancel");});
    cancellableCompleter.complete(
      //Future.value("future result"));
      Future.delayed(
        Duration(days: 1200),
        () => {
              print("i am here"),
              Navigator.push(context,
                  MaterialPageRoute(builder: (context) => DashboardPage())),
            }));
    cancellableCompleter.operation.value.then((value)=>print(value));
    cancellableCompleter.operation.value.whenComplete(()=>{print("Completed")});
    return RaisedButton(
      onPressed: _onButtonPressed,
      color: Colors.white,
      child: Text(
        "Log In",
        style: TextStyle(color: blue_color),
      ),
    );
  }

  _setAuthState() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    await sharedPreferences.setBool("isLoggedIn", true);
  }

  @override
  void dispose() {
    super.dispose();
    bloc.dispose();
  }
}

android
flutter
dart
asked on Stack Overflow Oct 17, 2019 by ashutosh • edited Oct 17, 2019 by ashutosh

2 Answers

1

Use BlocListener

return BlocListener<LoginBloc, LoginState>(
  listener: (context, state) {
    if (state is loginSuccess) {
      Navigator.push(context,MaterialPageRoute(builder: (context) => DashboardPage()));
    }
  },
  child: ButtonWidget(),
)
answered on Stack Overflow Apr 1, 2020 by AndreyStavitsky
0

First Set the widget on body of login then setState() call and then Navigator.push().Second solution is used the StreamBuilder for update design without setState().

answered on Stack Overflow Oct 17, 2019 by Avinash

User contributions licensed under CC BY-SA 3.0