Я не могу выполнить проверку формы для отдельных виджетов, как выполнить проверку формы для разделенных виджетов

#flutter #flutter-layout

Вопрос:

Я разделил виджеты формы на отдельные файлы, и теперь я пытаюсь проверить форму, но не работаю

Когда я объединил все виджеты в 1, проверка формы работала

Как выполнить проверку формы для отдельных виджетов

это следующий код, который я сделал в отдельных файлах

 class _OnBoardFormState extends State<OnBoardForm> {
final _formKey = GlobalKey<FormState>();


@override
Widget build(BuildContext context) {
return Container(
  padding: const EdgeInsets.only(left: 16, right: 16),
  child: Form(
    key: _formKey,
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: const [
        //Selection dropdown for first and Last Name

        OnBoardFormName(),
        SizedBox(height: 15),

        //Selection dropdown for Email

        OnBoardFormEmailField(),
        SizedBox(height: 15),

        //Selection dropdown for Gender

        OnBoardFormGenderField(),
        SizedBox(height: 15),

        //Selection dropdown for Age

        OnBoardAgeSelector(),
        SizedBox(height: 15),

        //Selection dropdown for Hight

        OnBoardHeightSelector(),
        SizedBox(height: 15),

        //Selection dropdown for Kgs and Lbs

        OnBoardWeightSelector(),
        SizedBox(height: 15),

        //Selection dropdown for Location

        OnBoardFormLocation(),
        SizedBox(height: 40),

        //Button to submit the form
        //Continue button for next page

        OnBoardFormButton(),
          ],
         ),
       ),
    );
   }
  }
 

И это отдельные виджеты

  class _OnBoardAgeSelectorState extends State<OnBoardAgeSelector> {
  final _formKey = GlobalKey<FormState>();

  // age declarations
  var _selectedIndexForAge = "Age";
  var age = [];

  @override
  void initState() {
    super.initState();
    for (int i = 18; i <= 120; i  ) {
      age.add(i);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text(
          'AGE',
          style: TextConstants.feildHeadText,
        ),
        const SizedBox(
          height: 2,
        ),
        SizedBox(
          height: 51,
          child: OutlineButton(
            
            shape: const StadiumBorder(),
            padding: const EdgeInsets.only(left: 20, right: 10),
            highlightedBorderColor: Colors.grey,
            borderSide: BorderSide(
              color: Colors.grey.shade500,
              width: 1,
            ),
            onPressed: () {
              // if (_formKey.currentState!.validate()) {
              //   const Text(
              //     "Please select Age",
              //     style: TextStyle(
              //       color: Colors.red,
              //       fontSize: 16,
              //     ),
              //   );
              // }
              showModalBottomSheet(
                context: context,
                builder: (BuildContext context) {
                  return SizedBox(
                    height: 200,
                    child: CupertinoPicker(
                      itemExtent: 32,
                      onSelectedItemChanged: (int index) {
                        setState(
                          () {
                            _selectedIndexForAge = age[index].toString();
                          },
                        );
                      },
                      children: List<Widget>.generate(
                        age.length,
                        (int index) {
                          return Center(
                            child: Text(age[index].toString()),
                          );
                        },
                      ),
                    ),
                  );
                },
              );
            },
            child: Stack(
              children: [
                Align(
                  alignment: Alignment.centerRight,
                  child: SvgPicture.asset('assets/icons/dropdown.svg'),
                ),
                Align(
                  alignment: Alignment.centerLeft,
                  child: Text(
                    _selectedIndexForAge.toString(),
                    textAlign: TextAlign.right,
                    style: TextConstants.fieldPlaceholderText,
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    );
    }
  }
 

и так далее, и другие виджеты

когда я пытаюсь проверить, он показывает такую ошибку

введите описание изображения здесь

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

1. Не могли бы вы объяснить немного подробнее? Не совсем понимаю ваш вопрос

2. конечно, всего несколько минут, пожалуйста

3. пожалуйста, проверьте это сейчас @s.am.i

Ответ №1:

Вам нужно добавить кнопку внутри формы, чтобы проверить правильность проверки.

Сначала вам нужно завернуть их в леску

Вы можете использовать _formKey.currentState!.проверка()

Для проверки всех виджетов saperate, которые определены в файлах saperate, таких как «Textformfield» и все…

Но все виджеты saperate должны находиться под виджетом формы и иметь ключ for.

Код (Ваш обновленный код)

 import 'package:flutter/material.dart';
import 'package:stackexample/onbordname.dart';

class OnBoardForm extends StatefulWidget {
  const OnBoardForm({Key? key}) : super(key: key);

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

class _OnBoardFormState extends State<OnBoardForm> {
  final _formKey = GlobalKey<FormState>();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        padding: const EdgeInsets.only(left: 16, right: 16),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              //Selection dropdown for first and Last Name

              OnBoardFormName(),
              SizedBox(height: 15),

              //Selection dropdown for Email
              OnBoardFormName(),
              // OnBoardFormEmailField(),
              SizedBox(height: 15),

              //Selection dropdown for Gender
              OnBoardFormName(),
              // OnBoardFormGenderField(),
              SizedBox(height: 15),

              //Selection dropdown for Age

              // OnBoardAgeSelector(),
              SizedBox(height: 15),

              //Selection dropdown for Hight

              // OnBoardHeightSelector(),
              SizedBox(height: 15),

              //Selection dropdown for Kgs and Lbs

              // OnBoardWeightSelector(),
              SizedBox(height: 15),

              //Selection dropdown for Location

              // OnBoardFormLocation(),
              SizedBox(height: 40),
              Padding(
                padding: EdgeInsets.symmetric(vertical: 16.0),
                child: ElevatedButton(
                  onPressed: () {
                    if (_formKey.currentState!.validate()) {
                      ScaffoldMessenger.of(context).showSnackBar(
                        const SnackBar(content: Text('Good to go...')),
                      );
                    }
                  },
                  child: const Text('Submit'),
                ),
              ),

              //Button to submit the form
              //Continue button for next page

              // OnBoardFormButton(),
            ],
          ),
        ),
      ),
    );
  }
}
 

Текстовое поле

 import 'package:flutter/material.dart';

class OnBoardFormName extends StatefulWidget {
  const OnBoardFormName({Key? key}) : super(key: key);

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

class _OnBoardFormNameState extends State<OnBoardFormName> {
  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text(
          'FIRST NAME',
          // style: TextConstants.feildHeadText,
        ),
        const SizedBox(
          height: 2,
        ),
        TextFormField(
          // style: TextConstants.fieldPlaceholderText,
          maxLength: 30,
          textCapitalization: TextCapitalization.words,
          autofocus: false,
          decoration: const InputDecoration(
            counterText: "",
            contentPadding: EdgeInsets.only(left: 20.0, right: 10.0),
            border: OutlineInputBorder(
              borderSide: BorderSide(
                color: Color(0xffE3E5F6),
                width: 1,
              ),
              borderRadius: BorderRadius.all(Radius.circular(40)),
            ),
            hintText: 'First Name',
          ),
          validator: (value) {
            if (value == null || value.isEmpty) {
              return 'Please enter first name';
            }
            return value.length < 3
                ? 'Name must be at least 3 to 30 characters long'
                : null;
          },
        ),
      ],
    );
  }
}
 

Выход

Проверка работает, когда показатель меньше 3

введите описание изображения здесь

Проверка истинна

введите описание изображения здесь

Обновить

Вы не можете поместить кнопку в новый файл, потому что вы не можете получить доступ к состоянию этого ключа формы

Если вы строго хотите поместить кнопку на другой файл, вам нужно передать ключ формы на новый экран ( или файл ). или используйте библиотеку управления состоянием, такую как » Блок или поставщик «

Но сейчас я предпочитаю поместить кнопку в тот же файл.

Спасибо

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

1. он работает для текстового поля, но как я могу сделать это для кнопки «Контур»? это дает ту же ошибку, что и выше

2. вы не можете использовать кнопку в другом файле. это «СОСТОЯНИЕ» должно быть внутри того же файла,или,если вы строго хотите, чтобы кнопка открывала следующий файл, вам нужно передать ключ формы в следующий файл или использовать любую библиотеку управления состоянием, например «БЛОК, поставщик, Getx… и т. Д.». Но сейчас я думаю, что лучше поместить ключ формы в сам файл формы

Ответ №2:

 final form = _formKey.currentState;
if (form.validate()){
   form.save();
}
 

Это должно быть внутри формы, форма должна иметь _formkey, кроме того, вы можете использовать режим автоматической проверки. Я думаю, проблема в вашей форме.validate() не находится внутри формы.

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

1. о, хорошо, понял, я подумал, что мы можем позвонить в другой файл, спасибо за ответ

2. Если бы это была полная помощь, сделайте ее приемлемым ответом.

3. он работает для текстового поля, но как я могу сделать это для кнопки «Контур»? это дает ту же ошибку, что и выше, и мне нужно отобразить ошибку для каждого поля

4. Вы имеете в виду проверку с помощью кнопки «Контур»? или кнопка проверить контур

5. кнопка проверить контур