0

想要根据用户输入启用/禁用按钮。如果所有文本输入都匹配某个条件,则只有启用“插入”按钮。

通常,如果所有输入字段都正确,按钮才会启用。但是,如果一个或多个不正确,并且用户移动到另一个输入字段,并将其更改为正确/不正确,则即使某些字段输入错误,按钮也会启用。检查图像:

在此处输入图像描述

登录块代码:

import 'package:rxdart/rxdart.dart';

class LoginScreenBloc {
  final _firstCtrl = BehaviorSubject<String>();
  final _lastCtrl = BehaviorSubject<String>();
  final _userNameCtrl = BehaviorSubject<String>();
  final _passwordCtrl = BehaviorSubject<String>();

  Function(String) get changeFirst => _firstCtrl.sink.add;
  Function(String) get changeLast => _lastCtrl.sink.add;
  Function(String) get changeUser => _userNameCtrl.sink.add;
  Function(String) get changePass => _passwordCtrl.sink.add;

  final fieldSize = StreamTransformer<String, String>.fromHandlers(
    handleData: (value, sink) {
      if (value.length > 3) {
        sink.add(value);
      } else {
        sink.addError("Can't be Empty!");
      }
    },
  );

  Stream<String> get firstname => _firstCtrl.stream.transform(fieldSize);
  Stream<String> get lastname => _lastCtrl.stream.transform(fieldSize);
  Stream<String> get username => _userNameCtrl.stream.transform(fieldSize);
  Stream<String> get password => _passwordCtrl.stream.transform(fieldSize);

  void insertValue() {
    print("${_firstCtrl.value}");
    print("${_lastCtrl.value}");
    print("${_userNameCtrl.value}");
    print("${_passwordCtrl.value}");
  }

  Stream<bool> get insertButton {
    return CombineLatestStream(
      [firstname, lastname, username, password],
      (values) {
        return true;
      },
    );
  }

  dispose() {
    _firstCtrl.close();
    _lastCtrl.close();
    _userNameCtrl.close();
    _passwordCtrl.close();
  }
}

按钮代码:

Widget insertValue(BuildContext context, LoginScreenBloc bloc) {
  return StreamBuilder<Object>(
    stream: bloc.insertButton,
    builder: (context, snapshot) {
      return RaisedButton(
        child: Text("Insert"),
        onPressed: snapshot.hasData ? bloc.insertValue : null,
      );
    },
  );
}
4

3 回答 3

0

你可以在这里找到类似的东西

    Stream<bool> get insertButton {
        return CombineLatestStream(
          [firstname, lastname, username, password],
          (values) {
            for(String i in values) {
               if(i.length < 3) return false;
            }
            return true;
          },
        );
      }

combineLatest 仅检查事件。它不处理从流中流出的错误。

于 2019-12-24T09:18:49.847 回答
0

尝试使用不透明度连接来启用按钮并设置点击和可见性的条件..像这样..

            Container(
          child: Opacity(opacity: isValid ? 1.0 : 0.7,
            child: RaisedButton(
              color: Colors.red,
              onPressed: _loginPressed,

              child: Text('Sign In',
                  style: TextStyle(fontSize: 15.0, color: Colors.white)),
            ),
          ),

        ),
于 2019-05-24T05:38:09.347 回答
0

我找到了一个适合我的解决方案。我在构建登录表单时遇到了同样的问题。

这是我的代码:


class LoginFormManager with FormValidatorMixin {
  final _email = BehaviorSubject<String>();
  Stream<String> get email$ => _email.stream.transform(emailValidator);
  Function(String) get setEmail => _email.sink.add;

  final _password = BehaviorSubject<String>();
  Stream<String> get password$ => _password.stream.transform(passwordValidator);
  Function(String) get setPassword => _password.sink.add;

  Stream<bool> get isFormValid$ =>
      CombineLatestStream.combine2<String, String, bool>(email$, password$,
          (email, password) {
        if (email == _email.value && password == _password.value) {
          return true;
        } else
          return false;
      });

  void submit() {
    print(_email.value);
    print(_password.value);
  }

  void dispose() {
    _email.close();
    _password.close();
  }
}

主题 _email 和 _password 存储最后收到的值,包括错误。email$ 和 password$ 流仅在从用户收到的输入通过验证器时发送数据。所以在我的例子中,我只需要检查 email$ 和 password$ 发送的 email 和 password$ 是否与存储在 _email 和 _password 的主题中的最后一个值匹配。

于 2020-01-29T01:01:00.767 回答