Flutter: закрыть DropdownButton (DropdownMenu)

Есть ли способ закрыть меню выбора DropdownButton, содержащее все DropdownMenuItems, при выполнении функции onTap (GestureDetector внутри DropdownMenuItem)?

2 ответа

Решение

Я просмотрел внутреннюю реализацию выпадающего списка в dart. Всплывающее меню раскрывающегося списка создается с помощью Navigator.push(). Он ожидает, пока пользователь щелкнет элемент, и возвращает значение с помощью Navigator.pop(). Таким образом, мы можем открыть всплывающее окно вручную, получив контекст раскрывающегося списка с помощью глобального ключа.

      void initState() {
    super.initState();
    dropdownKey = GlobalKey();
}

...

      DropdownButton<Boat>(
    key: dropdownKey,

...

      GestureDetector(
    onTap: () {
        Navigator.pop(dropdownKey.currentContext);

Полный код:

      class _BoatSelectionState extends State<BoatSelection> {
  GlobalKey dropdownKey;
  
  @override
  void initState() {
    super.initState();
    dropdownKey = GlobalKey(); // Init GlobalKey, allows to close the DropdownButton
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          child: 
            DropdownButtonHideUnderline(
              child: DropdownButton<Boat>(
                key: dropdownKey,
                icon: Icon(
                  Icons.keyboard_arrow_down_rounded,
                  color: Colors.black,
                ),
                isExpanded: true,
                value: selectedBoat,
                onChanged: (Boat _boat) => Provider.of<BoatStreamsCubit>(context, listen: false).setBoat(_boat),
                selectedItemBuilder: (BuildContext context) {
                  return widget.boats.map<Widget>((Boat boat) {
                    return Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        BoatClassLogo(boat: boat),
                        Expanded(
                          child: Padding(
                            padding: const EdgeInsets.only(left: DesignValues.paddingMd),
                            child: BoatInformation(boat: boat),
                          ),
                        ),
                      ],
                    );
                  }).toList();
                },
                items: widget.boats.map<DropdownMenuItem<Boat>>((Boat _boat) {
                  return DropdownMenuItem<Boat>(
                    value: _boat,
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Padding(
                          padding: const EdgeInsets.only(right: DesignValues.paddingMd),
                          child: BoatClassLogo(boat: _boat),
                        ),
                        Expanded(
                          child: BoatInformation(boat: _boat),
                        ),
                        GestureDetector(
                          onTap: () {
                            Navigator.pop(dropdownKey.currentContext); // Closes the dropdown
                            Navigator.push(context, MaterialPageRoute(builder: (context) => BoatForm(CreationState.edit, _boat)));
                          },
                          child: Padding(
                            padding: const EdgeInsets.symmetric(horizontal: 5.0),
                            child: Icon(
                              Icons.edit,
                              color: AppColors.primary,
                            ),
                          ),
                        ),
                      ],
                    ),
                  );
                }).toList(),
              ),
          ),
        ),
      ],
    );
  }
}

Если я вас понял, вы можете использовать узел фокуса для раскрывающегося меню.

      FocusNode dropdown;

Требуется инициализация в initstate;

      dropdown = FocusNode();

child: DropdownButtonHideUnderline(
                         child: DropdownButton <String>(
                            focusNode: dropdown,

Затем, когда вы можете подумать о закрытии этого меню, выполните в ontap;

        dropdown.unfocus();
Другие вопросы по тегам