Flutter:BlocConsumer不监听块传递的状态

nkkqxpd9  于 2023-05-23  发布在  Flutter
关注(0)|答案(1)|浏览(175)

我有授权页。在用户点击“登录”之后,授权发生并且块返回所需的状态。但是我的BlocConsumer并没有改变它,而是保留了初始状态“Initial State”。下面是我的项目的一部分代码。我将感激你的帮助!

app.dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:resourse_app/features/auth/auth_screen.dart';
import 'package:resourse_app/theme/theme.dart';
import 'package:resourse_app/utils/router/router.dart';

import 'features/auth/bloc/auth_bloc.dart';

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider (
          create: (BuildContext context) => AuthBloc(),
        ),
      ],
      child: MaterialApp(
        theme: lightTheme,
        home: const AuthScreen(),
        routes: router,
      ),
    );
  }
}

bloc.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:resourse_app/repositories/models/users/user.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

part 'auth_event.dart';

part 'auth_state.dart';

class AuthBloc extends Bloc<AuthEvent, AuthState> {
  AuthBloc() : super(AuthInitialState()) {
    FirebaseAuth auth = FirebaseAuth.instance;
    on<AuthSignInEvent>((event, emit) async {
      emit(AuthLoadingState());
      try {
        final user = event.user;
        await auth.signInWithEmailAndPassword(
            email: user.login, password: user.password);
        emit(AuthSignInState());
      } on FirebaseAuthException catch (e) {
        if (e.code == 'user-not-found') {
          emit(AuthFailureState(
              failureException: 'No user found for that email.'));
        } else if (e.code == 'wrong-password') {
          emit(AuthFailureState(
              failureException: 'Wrong password provided for that user.'));
        }
      } catch (error) {
        emit(AuthFailureState(failureException: error));
      }
      print("Переданный $state");
    });
    on<AuthSignUpEvent>((event, emit) async {
      emit(AuthLoadingState());
      try {
        final user = event.user;
        final UserCredential userCredential =
            await auth.createUserWithEmailAndPassword(
                email: event.user.login, password: event.user.password);

        await FirebaseFirestore.instance
            .collection('users')
            .doc(userCredential.user!.uid)
            .set({
          'userId': userCredential.user!.uid,
          'mail' : user.login,
          'username' : user.username,
        });
      } on FirebaseAuthException catch (e) {
        if (e.code == 'weak-password') {
          emit(AuthFailureState(
              failureException: 'The password provided is too weak.'));
        } else if (e.code == 'email-already-in-use') {
          emit(AuthFailureState(
              failureException: 'The account already exists for that email.'));
        }
      } catch (error) {
        emit(AuthFailureState(failureException: error));
      }
    });
  }
}

event.dart

part of 'auth_bloc.dart';

abstract class AuthEvent {}

class AuthSignInEvent extends AuthEvent {
  final UserSignIn user;

  AuthSignInEvent({required this.user});
}

class AuthSignUpEvent extends AuthEvent {
  final UserSignUp user;

  AuthSignUpEvent({required this.user});
}

state.dart

part of 'auth_bloc.dart';

abstract class AuthState {}

class AuthInitialState extends AuthState {}

class AuthSignInState extends AuthState {}

class AuthSignUpState extends AuthState {}

class AuthLoadingState extends AuthState {}

class AuthFailureState extends AuthState {
  final Object failureException;

  AuthFailureState({required this.failureException});
}

signInScreen.dart

import 'package:flutter/material.dart';
import 'package:resourse_app/features/auth/widgets/sign_up_screen/sign_up.dart';

import '../../../../../repositories/models/users/user.dart';
import '../../../bloc/auth_bloc.dart';

class SignInScreen extends StatefulWidget {
  static const String id = 'sign_in_screen';
  const SignInScreen({Key? key}) : super(key: key);

  @override
  State<SignInScreen> createState() => _SignInScreenState();
}

class _SignInScreenState extends State<SignInScreen> {
  final _formKey = GlobalKey<FormState>();

  late final FocusNode _passFocusNode;

  final _authBloc = AuthBloc();

  String? _email;
  String? _pass;

  @override
  void initState() {
    _passFocusNode = FocusNode();
    super.initState();
  }

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

  void _submit(BuildContext context) {
    FocusScope.of(context).unfocus();

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

    _formKey.currentState!.save();

    UserSignIn user = UserSignIn(login: _email!, password: _pass!);

    _authBloc.add(AuthSignInEvent( user: user,));
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context).textTheme;
    double wh = MediaQuery.of(context).size.width;
    double hh = MediaQuery.of(context).size.height;

    return GestureDetector(
      onTap: () {
        FocusScope.of(context).unfocus();
      },
      child: Scaffold(
        body: SafeArea(
          child: Center(
            child: Form(
              key: _formKey,
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20),
                child: ListView(
                  physics: BouncingScrollPhysics(),
                  shrinkWrap: true,
                  children: [
                    Center(
                      child: Text(
                        'Resourse',
                        style: theme.titleMedium,
                      ),
                    ),
                    SizedBox(
                      height: 35,
                    ),
                    //e-mail
                    SizedBox(
                      height: 40,
                      child: TextFormField(
                        style: theme.labelSmall,
                        decoration: InputDecoration(
                          enabledBorder: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(10),
                            borderSide: const BorderSide(
                                color: Colors.grey, width: 1.0),
                          ),
                          focusedBorder: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(10),
                            borderSide: const BorderSide(
                                color: Colors.white, width: 1.0),
                          ),
                          labelText: "Телефон или e-mail",
                        ),
                        onFieldSubmitted: (_) {
                          FocusScope.of(context).requestFocus(_passFocusNode);
                        },
                        onSaved: (value) {
                          _email = value;
                        },
                        validator: (value) {
                          if (value!.isEmpty) {
                            return 'Укажите телефон или e-mail';
                          }
                          return null;
                        },
                      ),
                    ),
                    SizedBox(
                      height: 15,
                    ),
                    //password
                    SizedBox(
                      height: 40,
                      child: TextFormField(
                        focusNode: _passFocusNode,
                        style: theme.labelSmall,
                        decoration: InputDecoration(
                          enabledBorder: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(10),
                            borderSide: const BorderSide(
                                color: Colors.grey, width: 1.0),
                          ),
                          focusedBorder: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(10),
                            borderSide: const BorderSide(
                                color: Colors.white, width: 1.0),
                          ),
                          labelText: "Пароль",
                        ),
                        obscureText: true,
                        onFieldSubmitted: (_) {
                          //TODO:- submit
                        },
                        onSaved: (value) {
                          _pass = value;
                        },
                        validator: (value) {
                          if (value!.isEmpty) {
                            return 'Введите пароль';
                          }
                          return null;
                        },
                      ),
                    ),
                    Align(
                      alignment: Alignment.centerRight,
                      child: TextButton(
                        onPressed: () {},
                        child: Text(
                          'забыли пароль?',
                          style: theme.labelSmall,
                        ),
                      ),
                    ),
                    //Вход
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        //Вход
                        SizedBox(
                          width: wh * 0.3,
                          child: ElevatedButton(
                            style: ButtonStyle(
                              backgroundColor: MaterialStateProperty.all<Color>(
                                  Colors.white),
                              shape:
                              MaterialStateProperty.all<RoundedRectangleBorder>(
                                RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10.0),
                                ),
                              ),
                            ),
                            onPressed: () {
                              _submit(context);
                            },
                            child: Text(
                              'Войти',
                              style: theme.labelMedium,
                            ),
                          ),
                        ),
                        SizedBox(width: 20,),
                        ElevatedButton(
                          style: ButtonStyle(
                            backgroundColor:
                            MaterialStateProperty.all<Color>(Colors.transparent),
                            shape:
                            MaterialStateProperty.all<RoundedRectangleBorder>(
                              RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(10.0),
                              ),
                            ),
                            side: MaterialStateProperty.all(
                              const BorderSide(
                                color: Colors.grey,
                                width: 1.0,
                              ),
                            ),
                          ),
                          onPressed: () {},
                          child: const Text(
                            'Войти с помощью google',
                            style:  TextStyle(
                                fontFamily: "Ysabeau",
                                fontSize: 15,
                                color: Colors.white,
                                fontWeight: FontWeight.w400
                            ),
                          ),
                        ),
                      ],
                    ),
                    SizedBox(
                      height: 15,
                    ),
                    Align(
                      alignment: Alignment.center,
                      child: Text(
                        'или',
                        style: theme.labelSmall,
                      ),
                    ),
                    SizedBox(
                      height: 15,
                    ),
                    ElevatedButton(
                      style: ButtonStyle(
                        backgroundColor:
                        MaterialStateProperty.all<Color>(Colors.transparent),
                        shape:
                        MaterialStateProperty.all<RoundedRectangleBorder>(
                          RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(10.0),
                          ),
                        ),
                        side: MaterialStateProperty.all(
                          const BorderSide(
                            color: Colors.grey,
                            width: 1.0,
                          ),
                        ),
                      ),
                      onPressed: () {
                        Navigator.of(context).pushNamed(SignUpScreen.id);
                      },
                      child: const Text(
                        'Зарегистрироваться',
                        style:  TextStyle(
                            fontFamily: "Ysabeau",
                            fontSize: 15,
                            color: Colors.white,
                            fontWeight: FontWeight.w400
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

授权dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:resourse_app/features/home_page/view/home_page.dart';

import '../bloc/auth_bloc.dart';
import '../widgets/sign_in_screen/sign_in.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: BlocConsumer<AuthBloc, AuthState>(
        listener: (context, state) {
          print(state);
          if (state is AuthSignInState || state is AuthSignUpEvent) {
            Navigator.of(context).popAndPushNamed(HomePage.id);
          }
        },
        builder: (context, state) {
          print("Переданный в widget $state");
              if (state is AuthLoadingState) {
                return const Center(
                  child: CircularProgressIndicator(
                    color: Colors.white,
                  ),
                );
              }
              if (state is AuthFailureState) {
                return AlertDialog(
                  title: Text(state.failureException.toString()),
                );
              }
              return const SignInScreen();
            }
      ),
    );
  }
}
3htmauhk

3htmauhk1#

final _authBloc = AuthBloc();

  String? _email;
  String? _pass;

  @override
  void initState() {
    _passFocusNode = FocusNode();
    super.initState();
  }

改为

late final _authBloc;
@override
      void initState() {
    _authBloc = context.read();
    //or _authBloc=context.read<AuthBloc>();
        _passFocusNode = FocusNode();
        super.initState();
      }

相关问题