Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 如何在颤振应用程序中正确使用BlocListener和BlocProvider_Flutter_Flutter Bloc_Flutter Packages - Fatal编程技术网

Flutter 如何在颤振应用程序中正确使用BlocListener和BlocProvider

Flutter 如何在颤振应用程序中正确使用BlocListener和BlocProvider,flutter,flutter-bloc,flutter-packages,Flutter,Flutter Bloc,Flutter Packages,我在我的flatter应用程序中使用了flatter_bloc 4.0.0,我使用了Felix Angelov的示例,使用bloc模式实现登录或登录流。它工作得很好,但是在我更新了我的颤振并检查了我的代码之后,我发现了一系列错误。我不明白他们为什么要来,因为上周一切都很好。在小部件的构建方法中实现bloc突然对我来说是错误的。我得到一个错误: 1.'无法从方法生成中返回BlocListener的值类型,因为它的返回类型为widget '无法从方法生成返回BlocProvider>的值类型,因为它

我在我的flatter应用程序中使用了flatter_bloc 4.0.0,我使用了Felix Angelov的示例,使用bloc模式实现登录或登录流。它工作得很好,但是在我更新了我的颤振并检查了我的代码之后,我发现了一系列错误。我不明白他们为什么要来,因为上周一切都很好。在小部件的构建方法中实现bloc突然对我来说是错误的。我得到一个错误:

1.'无法从方法生成中返回BlocListener的值类型,因为它的返回类型为widget

'无法从方法生成返回BlocProvider>的值类型,因为它的返回类型为widget' 第一个错误的代码

class LoginForm extends StatefulWidget {
  final UserRepository _userRepository;

  LoginForm({Key key, @required UserRepository userRepository})
      : assert(userRepository != null),
        _userRepository = userRepository,
        super(key: key);

  State<LoginForm> createState() => _LoginFormState();
}

class _LoginFormState extends State<LoginForm> {
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  LoginBloc _loginBloc;

  UserRepository get _userRepository => widget._userRepository;

  bool get isPopulated =>
      _emailController.text.isNotEmpty && _passwordController.text.isNotEmpty;

  bool isLoginButtonEnabled(LoginState state) {
    return state.isFormValid && isPopulated && !state.isSubmitting;
  }

  @override
  void initState() {
    super.initState();
    _loginBloc = BlocProvider.of<LoginBloc>(context);
    _emailController.addListener(_onEmailChanged);
    _passwordController.addListener(_onPasswordChanged);
  }

  @override
  Widget build(BuildContext context) {
    return BlocListener<LoginBloc, LoginState>(
      listener: (context, state) {
        if (state.isFailure) {
          Scaffold.of(context)
            ..hideCurrentSnackBar()
            ..showSnackBar(
              SnackBar(
                content: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [Text('Login Failure'), Icon(Icons.error)],
                ),
                backgroundColor: Colors.red,
              ),
            );
        }
        if (state.isSubmitting) {
          Scaffold.of(context)
            ..hideCurrentSnackBar()
            ..showSnackBar(
              SnackBar(
                content: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text('Logging In...'),
                    CircularProgressIndicator(),
                  ],
                ),
              ),
            );
        }
        if (state.isSuccess) {
          BlocProvider.of<AuthenticationBloc>(context).add(LoggedIn());
        }
      },
      child: BlocBuilder<LoginBloc, LoginState>(
        builder: (context, state) {
          return Padding(
            padding: EdgeInsets.all(20.0),
            child: Form(
              child: ListView(
                children: <Widget>[
                  Padding(
                    padding: EdgeInsets.symmetric(vertical: 20),
                    child: Image.asset('assets/flutter_logo.png', height: 200),
                  ),
                  Container(
                    margin: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 20.0),
                    height: 45.0,
                    child: TextFormField(
                      controller: _emailController,
                      style: TextStyle(
                        fontFamily: 'Avenir-Medium',
                        fontSize: 12.0,
                        color: Colors.black,
                      ),
                      decoration: InputDecoration(
                        border: OutlineInputBorder(
                            borderRadius: const BorderRadius.all(
                              const Radius.circular(7.0),
                            ),
                            borderSide: BorderSide(
                              color: Colors.grey[200],
                              width: 7.0,
                            )),
                        labelText: 'email',
                      ),
                      keyboardType: TextInputType.emailAddress,
                      autovalidate: true,
                      autocorrect: false,
                      validator: (_) {
                        return !state.isEmailValid ? 'Invalid Email' : null;
                      },
                    ),
                  ),
                  Container(
                    height: 45.0,
                    child: TextFormField(
                      style: TextStyle(
                        fontFamily: 'Avenir-Medium',
                        fontSize: 12.0,
                        color: Colors.black,
                      ),
                      controller: _passwordController,
                      decoration: InputDecoration(
                        border: OutlineInputBorder(
                            borderRadius: const BorderRadius.all(
                              const Radius.circular(7.0),
                            ),
                            borderSide: BorderSide(
                              color: Colors.grey[200],
                              width: 0.0,
                            )),
                        labelText: 'password',
                      ),
                      obscureText: true,
                      autovalidate: true,
                      autocorrect: false,
                      validator: (_) {
                        return !state.isPasswordValid ? 'Invalid Password' : null;
                      },
                    ),
                  ),
                  Padding(
                    padding: EdgeInsets.symmetric(vertical: 20),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: <Widget>[
                        LoginButton(
                          onPressed: _onFormSubmitted,

//                          isLoginButtonEnabled(state)
//                              ? _onFormSubmitted
//                              : null,
                        ),
                        GoogleLoginButton(),
                        AppleSignInButton(),
                        CreateAccountButton(userRepository: _userRepository),
                        ForgotPasswordButton()
                      ],
                    ),
                  ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }

  @override
  void dispose() {
    _emailController.dispose();
    _passwordController.dispose();
    super.dispose();
  }

  void _onEmailChanged() {
    _loginBloc.add(
      EmailChanged(email: _emailController.text),
    );
  }

  void _onPasswordChanged() {
    _loginBloc.add(
      PasswordChanged(password: _passwordController.text),
    );
  }

  void _onFormSubmitted() {
    _loginBloc.add(
      LoginWithCredentialsPressed(
        email: _emailController.text,
        password: _passwordController.text,
      ),
    );
  }
}

the code for the second error above is as follows

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  BlocSupervisor.delegate = SimpleBlocDelegate();
  final UserRepository userRepository = UserRepository();
  runApp(
    BlocProvider(
      create: (context) => AuthenticationBloc(
        userRepository: userRepository,
      )..add(AppStarted()),
      child: App(userRepository: userRepository),
    ),
  );
}

也许我的答案对你来说有点过时,但我希望它能帮助别人

首先,BlocBuilder/BlocListener应该在相应BlocProvider的范围内

您应该在无状态/有状态小部件的build方法中返回BlocBuilder。如果您想结合BlocListener和BlocBuilder,可以使用BlocConsumer小部件。此外,您可以添加参数buildWhen,以指定BlocBuilder是否应根据传入状态重建小部件。下面是一个例子:

class __ScreenWidgetState extends State<Screen> {

  @override
  Widget build(BuildContext context) {
    return BlocConsumer<ScreenBloc, ScreenState>(
      buildWhen: (previousState, state) {
        return state is! DontBuild;
      },
      builder: (BuildContext context, state) {
        return Text(state.text);
      },
      listener: (BuildContext context, state) {
        if (state is ShowFlushbar) {
          showFlushBar(context: context, message: state.text);
        }
      },
    );
  }
}
因此,我们的屏幕小部件作为它的子部件应该在ScreenBloc的范围内。我们可以通过以下方式实现这一目标:

BlocProvider<ScreenBloc>(
  create: (context) => ScreenBloc(),
  child: Screen(),
);