flutter 点击下拉按钮时防止键盘关闭

2g32fytz  于 2023-05-29  发布在  Flutter
关注(0)|答案(2)|浏览(200)

bounty还有2天到期。此问题的答案有资格获得+50声望奖励。poka正在寻找典型答案

当前的答案无法打开键盘。它使用了一个技巧来保持alertedialog的位置。
我们需要一个全局的解决方案来回答这个问题“防止键盘关闭时点击DropdownButton”。
如何保持焦点在文本字段,即使另一个部件,如下拉,被选中?
这个问题与Flutter有关。我在TextField上面有一个DropdownButton,如下所示:

DropdownButton<String>(
          isExpanded: true,
          hint: Text(associatedHint),
          disabledHint: Text(associatedHint),
          items: diagnosesList.map((int value) {
            return DropdownMenuItem<String>(
              value: value.toString(),
              child: Text(dxDisplay),
            );
          }).toList(),
          value: ANID,
          onChanged: (String newANID) {
            setState(() {
              ANID = newANID;
            });
          },
        ),
        TextField(
          autofocus: true,
          keyboardType: keyboardType,
          maxLines: maxLines,
          textCapitalization: TextCapitalization.sentences,
          controller: _textEntryController,
          decoration: InputDecoration(hintText: "Entry"),
          onChanged: (value) {
            noteEntry = value;
          },
        ),

TextField自动聚焦会立即显示键盘。当您点击下拉按钮时,它会从TextField中移除焦点,从而关闭键盘。这会在屏幕上移动东西,并产生糟糕的用户体验。

有什么建议可以解决这个问题吗?有没有一种方法,即使在点击下拉按钮后也能保持键盘向上?

2nbm6dog

2nbm6dog1#

终于找到了解决办法。需要将AlertDialog Package 在SingleChildScrollView中。这将打开屏幕顶部的AlertDialog,并且在键盘打开/关闭时不会移动它。它还确保如果内容太长(垂直),它可以在键盘下滑动,用户可以使用滚动手势查看/与隐藏的内容交互。

return SingleChildScrollView(
    child: AlertDialog(
      title: alertTitle,
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget> [
          DropdownButton<String>(
            .......
          ),
          TextField(
            autofocus: true,
            .......
          ),
        ],
      ),
    )
  );
f2uvfpb9

f2uvfpb92#

使用dropdown_button2的最佳解决方案

FocusNode focusNode = FocusNode();
  bool hasFocus = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Dropdown Fix'),
      ),
      body: Center(
        child: ListView(
          children: <Widget>[
            DropdownButton2(
              onMenuStateChange: (isOpen) {
                hasFocus = false;

                // this allows us to track whether or not you need to focus
                if (focusNode.hasFocus && isOpen && MediaQuery.of(context).viewInsets.bottom != 0) {
                  hasFocus = true;
                }

                if (hasFocus) {
                  // it should be called twice to provide focusNode being focused before DropdownButton2 inner calculations and after build method
                  focusNode.requestFocus();
                  WidgetsBinding.instance.addPostFrameCallback((_) => focusNode.requestFocus());
                }
              },
              isExpanded: true,
              hint: const Text('associatedHint'),
              disabledHint: const Text('associatedHint'),
              // don't forget to remove `const` when providing a new value
              items: const [
                DropdownMenuItem<String>(
                  value: 'value1',
                  child: Text('value1'),
                ),
                DropdownMenuItem<String>(
                  value: 'value2',
                  child: Text('value2'),
                ),
              ],
              onChanged: (_) {
                // 
              },
              iconStyleData: const IconStyleData(),
              dropdownStyleData: const DropdownStyleData(),
              menuItemStyleData: const MenuItemStyleData(),
            ),
            const SizedBox(height: 200),
            TextField(
              focusNode: focusNode,
              // autofocus: true,
              textCapitalization: TextCapitalization.sentences,
              decoration: const InputDecoration(hintText: "Entry"),
              maxLines: 1,
              onChanged: (value) {},
            ),
          ],
        ),
      ),
    );

相关问题