如何在flutter中从streambuilder导航到其他页面?

时间:2020-04-16 05:17:37

标签: authentication flutter bloc flutter-bloc

我正在尝试在flutter中使用bloc模式实现登录功能。因此,我想在身份验证成功后导航到主页。从loginBloc.dart,当状态为成功时,我将在login.dart的streamBuilder中获取状态。我想导航至main.dart,但我无法理解如何在login.dart的streamBuilder中调用main.dart。

login.dart


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_svg/svg.dart';
import 'package:hotelorders/bloc/LoginBloc.dart';
import 'package:hotelorders/screens/Home.dart';

class Login extends StatefulWidget
{
  @override
  State<StatefulWidget> createState() {
    return LoginState();
  }

}
class LoginState extends State<Login>
{
  final LoginBloc _loginBloc = LoginBloc();
  String _email,_password;
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  @override
  void dispose()
  {
    _loginBloc.dispose();
    super.dispose();
  }
  Widget _progressBar()
  {
    return StreamBuilder<bool>(
      stream: _loginBloc.progressStream,
      builder: (BuildContext context,AsyncSnapshot<bool> snapShot) {
        bool visible;
        if(snapShot.data == null)
          {
            visible = false;
          }
        else
          {
            visible = snapShot.data;
          }
        return Visibility(
          maintainSize: true,
          maintainAnimation: true,
          maintainState: true,
          visible: visible,
          child: Container(
              child: Center(
                  child: SizedBox(
                    width: 60,
                    height: 60,
                    child: Stack(
                      children: <Widget>[
                        Container(
                          decoration: BoxDecoration(
                            shape: BoxShape.circle,
                            color: Colors.white,
                            boxShadow: [
                              BoxShadow(
                                color: Colors.grey,
                                offset: Offset(0.0, 1.0), //(x,y)
                                blurRadius: 1.0,
                              ),
                            ],
                          ),
                        ),
                        Center(
                          child: CircularProgressIndicator(),
                        )
                      ],
                    ),
                  )
              )
          ),
        );
      }
    );
  }
  Widget _emailTextField()
  {
    return TextFormField(
      decoration: InputDecoration(
        labelText: "Email id",
        border: OutlineInputBorder(
          borderRadius: new BorderRadius.circular(32.0),
        )
      ),
      keyboardType: TextInputType.emailAddress,
      validator: (String value){
        if(value.isEmpty || !RegExp(r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?").hasMatch(value))
          {
            return "Enter a valid email id";
          }
        return null;
      },
      onSaved: (String value){
        _email = value;
      },
    );
  }
  Widget _passwordTextField()
  {
    return TextFormField(
      decoration: InputDecoration(labelText: "Password",
          filled: true,

          border: OutlineInputBorder(
            borderRadius: new BorderRadius.circular(32.0),
          ),
          fillColor: Colors.white
      ),
      keyboardType: TextInputType.text,
      obscureText: true,
      validator: (String value){
        if(value.isEmpty)
          {
            return "Enter a valid password";
          }
        else if(value.length < 8)
          {
            return "Password is too short";
          }
        else
          {
            return null;
          }
      },
    );
  }
  void _login()
  {

    if(!_formKey.currentState.validate())
      {
        return;
      }
    _formKey.currentState.save();

    Map<String,String> map = new Map();
    map['email'] = _email;
    map['password'] = _password;
    _loginBloc.login(map);
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          SingleChildScrollView(
              child: Container(
                child: Column(
                  children: <Widget>[
                    Container(
                      alignment: Alignment.center,
                      margin: EdgeInsets.fromLTRB(0, 48, 0, 0),
                      child: Text(
                        "Take Orders and",
                        style: TextStyle(color: Theme.of(context).primaryColorDark,fontSize: 20),
                      ),
                    ),
                    Container(
                      child: Text(
                        "Track the Best Selling Items",
                        style: TextStyle(color: Theme.of(context).primaryColor,fontSize: 16),
                      ),
                    ),
                    Container(
                      margin: EdgeInsets.fromLTRB(16, 0, 16, 0),
                      child: SvgPicture.asset('assets/images/undraw_booking.svg',width: 100.0,height: 280.0,),
                    ),
                    Container(
                      margin: EdgeInsets.fromLTRB(16, 0, 0, 0),
                      child:Row(
                        children: <Widget>[
                          Text(
                              "Login To ",
                              style: TextStyle(color: Colors.black,fontSize: 20)
                          ),
                          Text(
                            "Take orders",
                            style: TextStyle(color: Theme.of(context).primaryColorDark,fontSize: 20),
                          )
                        ],
                      ),
                    ),
                    Container(
                      margin: EdgeInsets.fromLTRB(16, 8, 16, 0),
                      child: Form(
                        key: _formKey,
                        child: Column(
                          children: <Widget>[
                            Container(
                              margin: EdgeInsets.fromLTRB(0, 8, 0, 0),
                              child:  _emailTextField(),
                            ),
                            Container(
                              margin: EdgeInsets.fromLTRB(0, 8, 0, 0),
                              child:  _passwordTextField(),
                            ),
                            Container(
                              margin: EdgeInsets.fromLTRB(0, 8, 0, 0),
                              child: Align(
                                alignment: Alignment.centerLeft,
                                child: RaisedButton(
                                  shape: RoundedRectangleBorder(
                                      borderRadius: BorderRadius.circular(32.0)
                                  ),
                                  padding: EdgeInsets.fromLTRB(64, 12, 64, 12),
                                  color: Theme.of(context).accentColor,
                                  textColor: Colors.white,
                                  child: Text(
                                    "Login",
                                  ),
                                  onPressed: (){
                                    _login();
                                  },
                                ) ,
                              ),
                            ),
                            StreamBuilder<dynamic>(
                              stream:_loginBloc.loginStateStream,
                              builder: (BuildContext context, AsyncSnapshot<dynamic> snapShot){
                                if(snapShot.data == "success")
                                  {
//                                    WidgetsBinding.instance.addPostFrameCallback((_){
//                                      Navigator.push(context, MaterialPageRoute(
//                                          builder: (context)=> Home()
//                                      ));
//                                    });
                                  }
                                else if(snapShot.data != null && snapShot.data != "success")
                                  {
                                    WidgetsBinding.instance.addPostFrameCallback((_) {
                                      Scaffold.of(context).showSnackBar(SnackBar(
                                        content: Text('${snapShot.data}',
                                          style: TextStyle(color: Colors.black),),
                                        backgroundColor: Color(0xFFe5e5e5),
                                      ));
//                                      showDialog(context: context,builder: (BuildContext con){
//                                        return AlertDialog(
//                                          title: Text('${snapShot.data}'),
//                                        );
//                                      });
                                    });
                                  }

                                return Container();
                              },
                            )
                          ],
                        ),
                      ),

                    )

                  ],
                ),
              )
          ),
          _progressBar(),
        ],
      ),
    );
  }

}

LoginBloc.dart

import 'dart:async';


class LoginBloc
{
  // here event comes in and state goes out
  //stream conntroller for output
  final _loginStateController = StreamController<String>();
  //stream controller for input
  final _loginEventController = StreamController<Map<String,String>>();

  final _progressController = StreamController<bool>();

  StreamSink<String> get loginStateSink => _loginStateController.sink;
  Stream<String> get loginStateStream => _loginStateController.stream;

  Sink<Map<String,String>> get loginEventSink => _loginEventController.sink;

  Stream<bool> get progressStream => _progressController.stream;
  StreamSink<bool> get progressSink => _progressController.sink;


  LoginBloc()
  {
    progressSink.add(false);
    _loginEventController.stream.listen(login);

  }

  login(Map<String,String> loginDetails)
  {
    progressSink.add(true);
    Timer(Duration(seconds: 3), () {
      progressSink.add(false);
      loginStateSink.add("success");
    });
    // when we pass data in sink we get the  output from stream

  }
  void dispose()
  {
    _loginEventController.close();
    _loginStateController.close();
    _progressController.close();
  }

}

1 个答案:

答案 0 :(得分:0)

您快到了。以下应该工作:

if(snapShot.data == "success")
{

    Navigator.push(
        context, MaterialPageRoute(builder: (context)=> Home()));

}

注意:WidgetsBinding.instance.addPostFrameCallback用于在加载小部件树时获取回调。