Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Bug ao usar componente DropdownButtonFormField

Estou tentado criar um app para aplicar o que estudei neste curso e estou travado com o DropdownButtonFormField. Estou fazendo um app ToDo. Este é o código de um StatefulWidget que criei.

class CategoryItems extends StatefulWidget {
  @override
  _CategoryItemsState createState() => _CategoryItemsState();
}

class _CategoryItemsState extends State<CategoryItems> {
  @override
  Widget build(BuildContext context) {
    String? _selected;

    return DropdownButtonFormField(
      onChanged: (dynamic newValue) {
        setState(() {
          newValue != null
              ? _selected = newValue.toString()
              : _selected = _selected;
        });
      },
      items: createDropDownItems(),
      value: _selected,
      hint: Text(FormLabels.category),
    );
  }

  List<DropdownMenuItem> createDropDownItems() {
    List<DropdownMenuItem>? _dropDown = <DropdownMenuItem<String>>[];

    _dropDown = Categories.toList().map<DropdownMenuItem<String>>((category) {
      return DropdownMenuItem<String>(
        child: Text(category),
        value: category,
      );
    }).toList();

    return _dropDown;
  }
}

Quando tento clicar no drop down os itens que criei aparecem e posso escolher cada um como esperado, porém o meu problema é que quando o usuário não aperta em nenhum dos itens do drop down. O app trava e o debug me leva para essa parte do código com uma linha destacada que parece ser o motivo do erro.

class _AsyncCompleter<T> extends _Completer<T> {
  void complete([FutureOr<T>? value]) {
    if (!future._mayComplete) throw new StateError("Future already completed");
    future._asyncComplete(value == null ? value as dynamic : value); //Esta linha é destacada pela IDE.
  }

  void _completeError(Object error, StackTrace stackTrace) {
    future._asyncCompleteError(error, stackTrace);
  }
}

Pelo o que entendi ao clicar fora do box do drop down o Flutter entende que você escolheu uma opção inválida (fora dos itens permitidos no drop down) e faz esse alerta. Porém não sei como contornar esse problema. Alguma sugestão de como resolver?

flutter --version
Flutter 2.0.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision c5a4b4029c (6 days ago) • 2021-03-04 09:47:48 -0800
Engine • revision 40441def69
Tools • Dart 2.12.0
1 resposta
solução!

Olá Felipe, por padrão o DropDown precisa que seu valor "default" seja um valor existente. Assim, mesmo quando o usuário não selecionar nada, a opção padrão é algo existente. E, pra forçar ele a informar na validação do formulário podemos criar uma regra que se o campo tiver aquele valor setado avisamos ao usuário que a resposta é inválida.

Normalmente crio uma primeira opção chamada "Selecione uma opção" por padrão. E forço o usuário a setar algo caso ele avance no formulário sem informar.

O ideal é atribuir ao String? _selected; um valor.

Caso tenha dúvidas com campos e afins, recomendo fazer nosso curso de formulários que saiu do forno fresquinho esse mês :).

Abração e bom estudo!