在 Flutter 中创建异步验证器

sup*_*ize 4 asynchronous dart flutter

我在Flutter中有一个异步函数,它将验证器的值作为参数:

validatePhone(number) {
  bool _isValid;

  Requests.get("http://apilayer.net/api/validate?value=$number", json: true)
      .then((val) {
    if (val['valid']) {
      // setState(() {  <- also tried setting state here
      _isValid = true;
      // });
    } else {
      // setState(() {
      _isValid = false;
      // });
    }
  });

  return _isValid;
}
Run Code Online (Sandbox Code Playgroud)

TextFormField(
  validator: (value) {
    if (value.isEmpty) {
      return 'Please your phone number';
    } else {
      if (validatePhone(value)) {
        return 'Your phone number is not valid';
      }
    }
  },
),
Run Code Online (Sandbox Code Playgroud)

但它不起作用,它总是返回null或在 中设置的初始值validatePhone。知道我怎样才能做到这一点吗?

Gia*_*ode 5

查看flutter_form_bloc,它支持异步验证器,除了提供其他优点之外,您还可以设置去抖时间。

您可以TextFieldBloc在没有 a 的情况下使用FormBloc,但如果在 a 内部使用它会更强大FormBloc

...
    _phoneFieldBloc = TextFieldBloc(
      asyncValidatorDebounceTime: Duration(milliseconds: 300),
      asyncValidators: [_validatePhone],
    );
...
Run Code Online (Sandbox Code Playgroud)
...
     TextFieldBlocBuilder(
       textFieldBloc: _phoneFieldBloc,
       suffixButton: SuffixButton.circularIndicatorWhenIsAsyncValidating,
       decoration: InputDecoration(labelText: 'Phone number'),
       keyboardType: TextInputType.phone,
     ),
...

Run Code Online (Sandbox Code Playgroud)

示例 #1 - 没有 FormBloc

dependencies:
  form_bloc: ^0.5.2
  flutter_form_bloc: ^0.4.3
Run Code Online (Sandbox Code Playgroud)
dependencies:
  form_bloc: ^0.5.2
  flutter_form_bloc: ^0.4.3
Run Code Online (Sandbox Code Playgroud)

示例 #2 - 使用 FormBloc

dependencies:
  form_bloc: ^0.5.2
  flutter_form_bloc: ^0.4.3
Run Code Online (Sandbox Code Playgroud)
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:form_bloc/form_bloc.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';

void main() => runApp(MaterialApp(home: HomeScreen()));

class HomeScreen extends StatefulWidget {
  HomeScreen({Key key}) : super(key: key);

  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  TextFieldBloc _phoneFieldBloc;

  StreamSubscription<TextFieldBlocState> _textFieldBlocSubscription;

  @override
  void initState() {
    super.initState();
    _phoneFieldBloc = TextFieldBloc(
      asyncValidatorDebounceTime: Duration(milliseconds: 300),
      asyncValidators: [_validatePhone],
    );

    _textFieldBlocSubscription = _phoneFieldBloc.state.listen((state) {
      if (state.isValid) {
        // Print the value of the _textFieldBloc when has a valid value
        print(state.value);
      }
    });
  }

  @override
  void dispose() {
    _phoneFieldBloc.dispose();
    _textFieldBlocSubscription.cancel();
    super.dispose();
  }

  Future<String> _validatePhone(String number) async {
    // Fake phone async validator
    await Future<void>.delayed(Duration(milliseconds: 200));
    if (number.length > 4 && number.length < 9) {
      return 'Your phone number is not valid';
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextFieldBlocBuilder(
          textFieldBloc: _phoneFieldBloc,
          suffixButton: SuffixButton.circularIndicatorWhenIsAsyncValidating,
          decoration: InputDecoration(labelText: 'Phone number'),
          keyboardType: TextInputType.phone,
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 注意:该库不再维护,无法在 flutter 2.0 及更高版本上运行 (2认同)