【问题标题】:Clickable icon on TextFormField - disable TextFormField focus on icon click (Flutter)TextFormField 上的可点击图标 - 禁用 TextFormField 对图标单击的关注(颤振)
【发布时间】:2020-01-25 13:37:30
【问题描述】:

我需要一个带有 suffixIcon 的 textField,但单击该图标后,我不需要打开键盘。如果没有 suffixIcon,我该如何做呢?

【问题讨论】:

  • 令人困惑。你想要一个带有后缀图标的文本字段吗?您想为后缀图标添加功能(使其可点击..)吗?您希望文本字段可聚焦吗?
  • 我想要 TextField 内的可点击图标,但是当我点击它时不显示键盘。
  • TextField 具有readOnly 属性,如果设置为true,则不会显示键盘。
  • 那么我将无法将一些数据放入 textField。我想如果我点击文本字段写一些文本,但如果我点击 suffixIcon 不显示键盘并执行一些操作

标签: android ios mobile flutter


【解决方案1】:
Container(
  child: Stack(
    alignment: Alignment.centerRight,
    children: <Widget>[
      TextField(),
      IconButton(
        icon: Icon(Icons.image),
        onPressed: () {
          // do something
        },
      ),
    ],
  ),
)

【讨论】:

  • 当TextField下方出现错误时,此解决方案不起作用,它使按钮不再垂直居中
【解决方案2】:

经过测试和确认,正是您想要的。

Stack(
  alignment: Alignment.centerRight,
  children: <Widget>[
    TextField(
      keyboardType: TextInputType.text,
      style: Theme.of(context).textTheme.body1,
      obscureText: true,
      decoration: InputDecoration(
        labelText: 'Password',
        contentPadding: const EdgeInsets.fromLTRB(6, 6, 48, 6), // 48 -> icon width
      ),
    ),
    IconButton(
      icon: Icon(Icons.dialpad, color: const Color(0xfff96800)),
      onPressed: () {
        FocusScope.of(context).requestFocus(FocusNode());
        // Your codes...
      },
    ),
  ],
),

【讨论】:

    【解决方案3】:

    这个问题还有一个可能的解决方法 - 取自这里:https://github.com/flutter/flutter/issues/39376 - 使用标准的 TextField 和一个按钮作为 suffixIcon,然后,魔术技巧:

    InputDecoration(labelText: "Email address",
        border: OutlineInputBorder(),
        suffixIcon: IconButton(
        iconSize: 40,
        icon: Icon(Icons.fingerprint),
        onPressed: () async {
          focusNode.unfocus();
          focusNode.canRequestFocus = false;
          await performBiometricLogin();
          focusNode.canRequestFocus = true;
        },
      ),
    ),
    

    在这种情况下您必须注意两件事:

    a) 在你的小部件中声明 focusNode(我在我的 statefull 小部件的状态类中这样做),然后将它用于你的文本字段:

    FocusNode focusNode = FocusNode();
    

    并在 TextField 中使用名为 focusNode 的属性:

    focusNode: focusNode,
    

    b) 如果您没有在 onPressed 事件处理程序中执行任何异步操作,那么您必须完全遵循 github 问题中的逻辑 - 一段时间后启用 canRequestFocus:

    Future.delayed(Duration(milliseconds: 100), () {
        widget.textFieldFocusNode.canRequestFocus = true;
    });
    

    希望它能像帮助我一样帮助其他人。

    谢谢。

    【讨论】:

    • 这很完美,无需堆栈即可保持 TextField 的清洁。我添加了一件事,因为如果 textField 被聚焦并且 suffixIcon 被点击,我不想失去焦点。在点击处理程序中添加 """if (textFieldFocusNode.hasPrimaryFocus) return;"""" 完成了这项工作。完整答案在这里stackoverflow.com/questions/49125064/…
    【解决方案4】:

    使用readOnly,不要使用enabled

    【讨论】:

      【解决方案5】:

      单击而不打开键盘?如果是这样,只需创建一个类并将其分配给focusNode,将hasFocus 设置为false,如下所示:

      class AlwaysDisabledFocusNode extends FocusNode {
        @override
        bool get hasFocus => false;
      }
      
      new TextField(
      focusNode: AlwaysDisabledFocusNode(),
      onTap: () {},
      keyboardType: TextInputType.text,
      decoration: InputDecoration(
      border: InputBorder.none,
      icon: Icon(Icons.apps),
      hintText: 'Password'),
      style: Theme.of(context).textTheme.body1,
      ),
      

      readOnly: true 会在点击时更改图标颜色

      new TextField(readOnly: true,
          //focusNode: AlwaysDisabledFocusNode(),
          onTap: () {},
          keyboardType: TextInputType.text,
          decoration: InputDecoration(
          border: InputBorder.none,
          icon: Icon(Icons.apps),
          hintText: 'Password'),
          style: Theme.of(context).textTheme.body1,
          ),
      

      我认为您必须将RowTextFieldIconButton 放在一起,并使用单独的操作。

      new Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          new Expanded(
              child: Padding(
            child: new TextField(
              onTap: () {//action of TextField
              },
              keyboardType: TextInputType.text,
              decoration: InputDecoration(
                  border: InputBorder.none, hintText: 'Password'),
              style: Theme.of(context).textTheme.body1,
            ),
            padding: EdgeInsets.only(left: 40),
          )),
          IconButton(
            icon: Icon(Icons.apps),
            onPressed: () {//action of iconbutton
            },
          )
        ],
      )
      

      【讨论】:

      • 我想如果我点击文本字段写一些文本,但如果我点击 suffixIcon 不显示键盘并执行一些操作
      • 当您单击 textField 和单击图标时,您在两个选项中都有键盘。只有当我点击 textField 时我才需要键盘
      【解决方案6】:

      我也做到了

      Container(
              height: 40,
              child: Stack(
                children: <Widget>[
                  TextField(
                    controller: textEditingController,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                      prefixIcon: Icon(HelageeIcons.search_icon_of_search_box),
                      border: OutlineInputBorder(
                        borderSide: BorderSide(
                          color: Color(0xff575656),
                        ),
                        borderRadius: const BorderRadius.all(
                          const Radius.circular(50.0),
                        ),
                      ),
                      hintStyle:
                          TextStyle(color: Color(0xffADADAC), fontSize: 14),
                      hintText: "Quick Search",
                    ),
                  ),
                  Positioned(
                    right: 0,
                    child: Container(
                      height: 40,
                      width: 40,
                      child: Container(
                        child: Material(
                            shape: CircleBorder(),
                            color: Colors.transparent,
                            child: InkWell(
                                customBorder: CircleBorder(),
                                onTap: () {},
                                splashColor: Colors.grey,
                                child: Icon(Icons.keyboard))),
                      ),
                    ),
                  ),
                ],
              ),
            ),
      

      【讨论】:

        【解决方案7】:

        添加后缀图标和后缀图标点击文本字段,在我的情况下我使用如下

        TextFormField(
            textInputAction: TextInputAction.done,
            maxLines: 1,
            obscureText: _obscureText,
            autofocus: false,
            focusNode: _passwordFocus,
            style: TextStyle(fontSize: 17.0, color: Colors.black),
            onFieldSubmitted: (term) {
              _passwordFocus.unfocus();
              _validateAndSubmit();
            },
            decoration: InputDecoration(
              hintText: HINT_PASSWORD,
              hintStyle: TextStyle(fontSize: 17.0, color: Colors.black54),
              focusedBorder: OutlineInputBorder(
                borderSide: BorderSide(color: Colors.black),
              ),
              enabledBorder: OutlineInputBorder(
                borderSide: BorderSide(color: Colors.black87),
              ),
              errorBorder: OutlineInputBorder(
                borderSide: BorderSide(color: Colors.red),
              ),
              disabledBorder: OutlineInputBorder(
                borderSide: BorderSide(color: Colors.black87),
              ),
              focusedErrorBorder: OutlineInputBorder(
                borderSide: BorderSide(color: Colors.red),
              ),
              labelText: HINT_PASSWORD,
              labelStyle: TextStyle(fontSize: 17.0, color: Colors.black),
              errorStyle: TextStyle(fontSize: 12.0, color: Colors.red),
              prefixIcon: Icon(
                Icons.lock,
                color: themeColor,
              ),
              /// magic is here suffix ixon click
              suffixIcon: IconButton(
                icon: Icon(
                  // Based on passwordVisible state choose the icon
                  _obscureText ? Icons.visibility : Icons.visibility_off,
                  color: themeColor,
                ),
                onPressed: () {
                  // Update the state i.e. toogle the state of passwordVisible variable
                  setState(() {
                    _obscureText ? _obscureText = false : _obscureText = true;
                  });
                },
              ),
            ),
            validator: validatePassword,
            onSaved: (value) => _password = value,
          )
        

        【讨论】:

        • 单击 suffixIcon 时您有活动键盘。它对我无效。
        【解决方案8】:

        这应该可以工作

        Stack(
                    alignment: Alignment.centerRight,
                    children: <Widget>[
                      TextFormField(
                      ),
                      FlatButton(
                        onPressed: () {
                          _openOrhidePassword();
                        },
                        child: Image(
                          height: 24.0,
                          width: 24.0,
                          image: AssetImage('images/Eye.png'),
                        ),
                      ),
                    ],
                  ),
        

        在我的情况下,图像大小是另一个问题。当我提供尺寸时,它可以很好地与其他小部件一起使用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-11
          • 2020-02-02
          • 1970-01-01
          • 2019-09-26
          • 2011-11-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多