Почему validate () в форме пропускает некоторые валидаторы (Flutter)? - PullRequest
0 голосов
/ 05 октября 2019

У меня проблемы с функцией validate(). Я не могу понять, почему он пропускает некоторые validator:(){}. Вот мой код:

import 'package:flutter/material.dart';

class TestScreen extends StatefulWidget {
  static const routeName = '/test-screen';

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

class _TestScreenState extends State<TestScreen> {
  final _form = GlobalKey<FormState>();

  Future<void> _saveForm() async {
    final isValid = _form.currentState.validate();
    if (!isValid) {
      return;
    }
  }

  Widget _buildContainer(Widget child) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        border: Border.all(color: Colors.grey),
        borderRadius: BorderRadius.circular(10),
      ),
      margin: EdgeInsets.all(10),
      padding: EdgeInsets.all(10),
      height: 200,
      width: 300,
      child: child,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Test',
          style: Theme.of(context).textTheme.title,
        ),
        automaticallyImplyLeading: false,
      ),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Form(
          key: _form,
          child: ListView(
            children: <Widget>[
              TextFormField(
                initialValue: '',
                decoration: InputDecoration(labelText: 'Name'),
                validator: (value) {
                  if (value.isEmpty) {
                    return 'Insert something';
                  }
                  return null;
                },
              ),
              TextFormField(
                initialValue: '',
                decoration: InputDecoration(labelText: 'Number'),
                keyboardType: TextInputType.number,
                validator: (value) {
                  if (int.tryParse(value) == null) {
                    return 'Insert a number';
                  }
                  return null;
                },
              ),
              SizedBox(height: 20),
              _buildContainer(
                ListView(
                  children: <Widget>[],
                ),
              ),
              Text(
                'Text-Test1',
                textAlign: TextAlign.center,
              ),
              Slider(
                value: 1,
                divisions: 3,
                min: 0.0,
                max: 3.0,
                label: 'Test',
                onChanged: (newValue) {},
              ),
              SizedBox(
                height: 20,
              ),
              Text(
                'Text-Test2',
                textAlign: TextAlign.center,
              ),
              Slider(
                value: 3,
                divisions: 4,
                min: 0.0,
                max: 4.0,
                label: 'Nothing2',
                onChanged: (newValue) {},
              ),
              SizedBox(
                height: 20,
              ),
              Row(
                children: <Widget>[
                  Text('RandomLabel'),
                  Spacer(),
                  Container(
                    width: 100,
                    child: TextFormField(
                      initialValue: '',
                      keyboardType: TextInputType.number,
                      validator: (value) {
                        if (int.tryParse(value) == null) {
                          return 'Insert a number';
                        }
                        return null;
                      },
                    ),
                  ),
                ],
              ),
              SizedBox(
                height: 20,
              ),
              Text(
                'Test 2',
                textAlign: TextAlign.center,
              ),
              _buildContainer(
                ListView.builder(
                  itemCount: 0,
                  itemBuilder: (ctx, index) {
                    return ListTile(
                      title: Text('hello'),
                      subtitle: Text('world'),
                    );
                  },
                ),
              ),
              TextFormField(
                initialValue: '',
                minLines: 4,
                maxLines: 4,
                decoration: InputDecoration(labelText: 'Text'),
                validator: (value) {
                  if (value.isEmpty) {
                    return 'Insert something';
                  }
                  return null;
                },
              ),
              FlatButton.icon(
                icon: Icon(Icons.check),
                label: Text('Done'),
                onPressed: () {
                  _saveForm();
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Если я нажимаю Готово, он пропускает первые два TextFormField с и проверяет один из Row. Очевидно, это не то, что я хочу. Как это исправить и проверить все TextFormField s?

1 Ответ

1 голос
/ 05 октября 2019

Оборачивание полей формы с помощью ListView - плохая идея: когда пользователь прокручивает до кнопки submit, некоторые входы располагаются, потому что они находятся вне экрана. Вы должны заменить ListView на Column виджет и обернуть всю форму в SingleChildScrollView:

class TestScreen extends StatefulWidget {
  static const routeName = '/test-screen';

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

class _TestScreenState extends State<TestScreen> {
  final _form = GlobalKey<FormState>();

  Future<void> _saveForm() async {
    final isValid = _form.currentState.validate();
    if (!isValid) {
      return;
    }
  }

  Widget _buildContainer(Widget child) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        border: Border.all(color: Colors.grey),
        borderRadius: BorderRadius.circular(10),
      ),
      margin: EdgeInsets.all(10),
      padding: EdgeInsets.all(10),
      height: 200,
      width: 300,
      child: child,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Test',
          style: Theme.of(context).textTheme.title,
        ),
        automaticallyImplyLeading: false,
      ),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(20.0),
          child: Form(
            key: _form,
            child: Column(
              children: <Widget>[
                TextFormField(
                  initialValue: '',
                  decoration: InputDecoration(labelText: 'Name'),
                  validator: (value) {
                    if (value.isEmpty) {
                      return 'Insert something';
                    }
                    return null;
                  },
                ),
                TextFormField(
                  initialValue: '',
                  decoration: InputDecoration(labelText: 'Number'),
                  keyboardType: TextInputType.number,
                  validator: (value) {
                    if (int.tryParse(value) == null) {
                      return 'Insert a number';
                    }
                    return null;
                  },
                ),
                SizedBox(height: 20),
                _buildContainer(
                  ListView(
                    children: <Widget>[],
                  ),
                ),
                Text(
                  'Text-Test1',
                  textAlign: TextAlign.center,
                ),
                Slider(
                  value: 1,
                  divisions: 3,
                  min: 0.0,
                  max: 3.0,
                  label: 'Test',
                  onChanged: (newValue) {},
                ),
                SizedBox(
                  height: 20,
                ),
                Text(
                  'Text-Test2',
                  textAlign: TextAlign.center,
                ),
                Slider(
                  value: 3,
                  divisions: 4,
                  min: 0.0,
                  max: 4.0,
                  label: 'Nothing2',
                  onChanged: (newValue) {},
                ),
                SizedBox(
                  height: 20,
                ),
                Row(
                  children: <Widget>[
                    Text('RandomLabel'),
                    Spacer(),
                    Container(
                      width: 100,
                      child: TextFormField(
                        initialValue: '',
                        keyboardType: TextInputType.number,
                        validator: (value) {
                          if (int.tryParse(value) == null) {
                            return 'Insert a number';
                          }
                          return null;
                        },
                      ),
                    ),
                  ],
                ),
                SizedBox(
                  height: 20,
                ),
                Text(
                  'Test 2',
                  textAlign: TextAlign.center,
                ),
                _buildContainer(
                  ListView.builder(
                    itemCount: 0,
                    itemBuilder: (ctx, index) {
                      return ListTile(
                        title: Text('hello'),
                        subtitle: Text('world'),
                      );
                    },
                  ),
                ),
                TextFormField(
                  initialValue: '',
                  minLines: 4,
                  maxLines: 4,
                  decoration: InputDecoration(labelText: 'Text'),
                  validator: (value) {
                    if (value.isEmpty) {
                      return 'Insert something';
                    }
                    return null;
                  },
                ),
                FlatButton.icon(
                  icon: Icon(Icons.check),
                  label: Text('Done'),
                  onPressed: () {
                    _saveForm();
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...