Как я могу реализовать проверку формы для нескольких форм в listview в flutter?

#flutter

#flutter

Вопрос:

Я создал виджет формы, который я использую для создания нескольких форм в виде списка. Я следую этой реализации: https://github.com/putraxor/flutter_multipage_form

По-видимому, проверка формы не работает. Когда я пытаюсь проверить каждую форму, я обнаруживаю (после отладки), что виджет не смонтирован, поэтому я получаю сообщение об ошибке:

Метод ‘validate’ был вызван для null. Получатель: null Попытался вызвать: validate()

Вот код:

Виджет формы

     typedef OnDelete();
        
        class UserForm extends StatefulWidget {
          final User user;
          final state = _UserFormState();
          final OnDelete onDelete;
        
          UserForm({Key key, this.user, this.onDelete}) : super(key: key);
          @override
          _UserFormState createState() => state;
        
          bool isValid() => state.validate();
        }
        
        class _UserFormState extends State<UserForm> {
          final form = GlobalKey<FormState>();
        
          @override
          Widget build(BuildContext context) {
            return Padding(
              padding: EdgeInsets.all(16),
              child: Material(
                elevation: 1,
                clipBehavior: Clip.antiAlias,
                borderRadius: BorderRadius.circular(8),
                child: Form(
                  key: form,
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      AppBar(
                        leading: Icon(Icons.verified_user),
                        elevation: 0,
                        title: Text('User Details'),
                        backgroundColor: Theme.of(context).accentColor,
                        centerTitle: true,
                        actions: <Widget>[
                          IconButton(
                            icon: Icon(Icons.delete),
                            onPressed: widget.onDelete,
                          )
                        ],
                      ),
                      Padding(
                        padding: EdgeInsets.only(left: 16, right: 16, top: 16),
                        child: TextFormField(
                          initialValue: widget.user.fullName,
                          onSaved: (val) => widget.user.fullName = val,
                          validator: (val) =>
                              val.length > 3 ? null : 'Full name is invalid',
                          decoration: InputDecoration(
                            labelText: 'Full Name',
                            hintText: 'Enter your full name',
                            icon: Icon(Icons.person),
                            isDense: true,
                          ),
                        ),
                      ),
                      Padding(
                        padding: EdgeInsets.only(left: 16, right: 16, bottom: 24),
                        child: TextFormField(
                          initialValue: widget.user.email,
                          onSaved: (val) => widget.user.email = val,
                          validator: (val) =>
                              val.contains('@') ? null : 'Email is invalid',
                          decoration: InputDecoration(
                            labelText: 'Email Address',
                            hintText: 'Enter your email',
                            icon: Icon(Icons.email),
                            isDense: true,
                          ),
                        ),
                      )
                    ],
                  ),
                ),
              ),
            );
          }
        
          ///form validator
          bool validate() {
            var valid = form.currentState.validate();
            if (valid) form.currentState.save();
            return valid;
          }
        }    
  

Виджет с несколькими формами

 class MultiForm extends StatefulWidget {
  @override
  _MultiFormState createState() => _MultiFormState();
}

class _MultiFormState extends State<MultiForm> {
  List<UserForm> users = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: .0,
        leading: Icon(
          Icons.wb_cloudy,
        ),
        title: Text('REGISTER USERS'),
        actions: <Widget>[
          FlatButton(
            child: Text('Save'),
            textColor: Colors.white,
            onPressed: onSave,
          )
        ],
      ),
      body: Container(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: [
              Color(0xFF30C1FF),
              Color(0xFF2AA7DC),
            ],
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
          ),
        ),
        child: users.length <= 0
            ? Center(
                child: EmptyState(
                  title: 'Oops',
                  message: 'Add form by tapping add button below',
                ),
              )
            : ListView.builder(
                addAutomaticKeepAlives: true,
                itemCount: users.length,
                itemBuilder: (_, i) => users[i],
              ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: onAddForm,
        foregroundColor: Colors.white,
      ),
    );
  }

  ///on form user deleted
  void onDelete(User _user) {
    setState(() {
      var find = users.firstWhere(
        (it) => it.user == _user,
        orElse: () => null,
      );
      if (find != null) users.removeAt(users.indexOf(find));
    });
  }

  ///on add form
  void onAddForm() {
    setState(() {
      var _user = User();
      users.add(UserForm(
        user: _user,
        onDelete: () => onDelete(_user),
      ));
    });
  }

  ///on save forms
  void onSave() {
    if (users.length > 0) {
      var allValid = true;
      users.forEach((form) => allValid = allValid amp;amp; form.isValid());
      if (allValid) {
        var data = users.map((it) => it.user).toList();
        Navigator.push(
          context,
          MaterialPageRoute(
            fullscreenDialog: true,
            builder: (_) => Scaffold(
                  appBar: AppBar(
                    title: Text('List of Users'),
                  ),
                  body: ListView.builder(
                    itemCount: data.length,
                    itemBuilder: (_, i) => ListTile(
                          leading: CircleAvatar(
                            child: Text(data[i].fullName.substring(0, 1)),
                          ),
                          title: Text(data[i].fullName),
                          subtitle: Text(data[i].email),
                        ),
                  ),
                ),
          ),
        );
      }
    }
  }
}
  

Как я могу заставить это работать?
Есть ли способ, которым я могу создать и получить доступ к методу проверки в состоянии виджета формы из другого виджета и использовать его для проверки?

Комментарии:

1. Вы исправили свою проблему? github.com/flutter/flutter/issues/56159