#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. кнопка проверить контур