Flutter - Как реализовать один виджет TextFormField для электронной почты для использования на нескольких экранах? - PullRequest
1 голос
/ 31 марта 2020

Я разрабатываю приложение с экраном регистрации, входа и сброса пароля. На всех этих экранах пользователь должен ввести свой адрес электронной почты. Теперь я не буду реализовывать текстовое поле адреса электронной почты для каждого экрана. Поэтому я буду реализовывать виджет текстового поля электронной почты для каждого экрана, как показано ниже.

import 'package:flutter/material.dart';
import 'package:email_validator/email_validator.dart';

class EMailTextFormField extends StatefulWidget {

  @override
  _EMailTextFormFieldState createState() => _EMailTextFormFieldState();
}

class _EMailTextFormFieldState extends State<EMailTextFormField> {
  final _email = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 3.0),
      child: TextFormField(
        decoration: InputDecoration(
          icon: Icon(Icons.email, size: IconTheme.of(context).size, color: IconTheme.of(context).color),
          labelText: 'E-Mail...',
          counterText: '',
        ),
        keyboardType: TextInputType.emailAddress,
        controller: _email,
        validator: _validateEmail,
        maxLength: 70,
      ),
    );
  }

  String _validateEmail(String email) {
    // validate E-Mail function...
  }
}

Моя проблема в том, что теперь я не могу использовать TextEditingController (_email) вне этого виджета на разных экранах (зарегистрируйтесь, введите логин и сбросьте пароль), например, в следующем примере:

final FirebaseUser user = (await _auth.createUserWithEmailAndPassword(
                  email: _email.text.toString(), password: _password.text.toString())).user;

Ошибка «Неопределенное имя _email», поскольку TextEditingController _email находится в виджете EMailTextFormField, но как я могу указать значение поля _email из Виджет EMailTextFormField для других экранов (регистрация, вход в систему и сброс пароля)?

Кто-нибудь может мне помочь, я пока не нашел решения.

1 Ответ

1 голос
/ 31 марта 2020

Вы можете сделать это с помощью onSaved обратного вызова.

EMailTextFormField:

class EMailTextFormField extends StatefulWidget {

  final void Function(String email) onSaved;

  const EMailTextFormField({Key key, this.onSaved}) : super(key: key);

  @override
  EMailTextFormFieldState createState() => EMailTextFormFieldState();
}

class EMailTextFormFieldState extends State<EMailTextFormField> {
  final _email = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 3.0),
      child: TextFormField(
        decoration: InputDecoration(
          icon: Icon(Icons.email, size: IconTheme.of(context).size, color: IconTheme.of(context).color),
          labelText: 'E-Mail...',
          counterText: '',
        ),
        keyboardType: TextInputType.emailAddress,
        controller: _email,
        validator: _validateEmail,
        maxLength: 70,
        onSaved: widget.onSaved, //callback
      ),
    );
  }

  String _validateEmail(String email) {
    // validate E-Mail function...
  }
}

Страница, на которой вы будете использовать EMailTextFormField:

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

  @override
  _EmailPageState createState() => _EmailPageState();
}

class _EmailPageState extends State<EmailPage> {

  String _email;

  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Email Page'),
      ),
      body: Form(
        key: _formKey,
        child: Column(
          children: <Widget>[
            EMailTextFormField(
              onSaved: (String email) => _email = email,
            ),
            RaisedButton(
              child: Text('Go'),
              onPressed: (){
                if (_formKey.currentState.validate()) {
                  _formKey.currentState.save();

                  print(_email);
                }
              },
            )
          ],
        ),
      ),
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...