Flutter文本字段在文本更改时禁用前缀图标

huangapple go评论62阅读模式
英文:

Flutter textfield disable prefix icon on text changed

问题

我有一个文本字段小部件,带有前缀图标。我希望当文本字段发生变化时,前缀图标被隐藏。

我的代码:

```dart
TextField(
  controller: messageInputController,
  onChanged: (value){
    messageInputChanged();
  },
  decoration: InputDecoration(
    counterText: '',
    prefixIcon: !showPrefixIcon ? Container() : Padding(
      padding: const EdgeInsets.all(0),
      child: IconButton(
        onPressed: () {
          imagePickerBottomSheet();
        },
        iconSize: 40,
        color: Skin.gray,
        icon: SvgPicture.asset(
          'assets/svg/ic-image.svg',
          height: 22,
          color: Skin.gray,
        ),
      ),
    ),
  ),
),
void messageInputChanged() {
  if(messageInputController.text.isEmpty){
    showPrefixIcon = true;
  }else {
    showPrefixIcon = false;
  }
  
  setState(() {});
}

但是当调用setState并隐藏图标时,文本字段的内容也会混乱。


<details>
<summary>英文:</summary>

I have a text field widget that has an prefix icon . I want the prefix icon to be hidden when the text field is changed

my code:

TextField(
controller: messageInputController,
onChanged: (value){
messageInputChanged();
},

                decoration: InputDecoration(
                    counterText: &#39;&#39;,
                    prefixIcon: !showPrefixIcon ? Container() :  Padding(
                      padding: const EdgeInsets.all(0),
                      child: IconButton(
                          onPressed: () {
                              imagePickerBottomSheet();
                          },
                          iconSize: 40,
                          color: Skin.gray,
                          icon: SvgPicture.asset(
                            &#39;assets/svg/ic-image.svg&#39;,
                            height: 22,
                            color: Skin.gray,
                          )),
                    ),
                ),
              ),

void messageInputChanged() {
if(messageInputController.text.isEmpty){
showPrefixIcon = true;
}else {
showPrefixIcon = false;
}

setState(() {});

}




But when the set state is called and the icon is hidden, the contents of the text field are also messed up

</details>


# 答案1
**得分**: 0

The InputDecorator接受一个Widget作为prefixIcon,但是它不支持Container()。这很奇怪。
如果我将你的

    prefixIcon: !showPrefixIcon ? Container() : Padding(...)

替换为

    prefixIcon: !showPrefixIcon ? SizedBox(height: 0.0, width: 0.0) : Padding(...)

它可以工作。
老实说,我真的不知道为什么。

---------
更新的建议:
使用:

    prefixIcon: !showPrefixIcon ? null : Padding(...)

----------

我只是假设你可以合理地认为这样做很丑陋。然后,我担心,你必须改变做法,像这样:

```dart
@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Center(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Container(
          height: 70.0,
          decoration: BoxDecoration(
              border: Border.all(
                color: Colors.blue,
              ),
              borderRadius: const BorderRadius.all(Radius.circular(10))),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              AnimatedSwitcher(
                  duration: const Duration(milliseconds: 600),
                  transitionBuilder: (child, animation) => SizeTransition(
                      sizeFactor: animation,
                      axis: Axis.horizontal,
                      child: child),
                  child: showPrefixIcon
                      ? const Padding(
                          padding: EdgeInsets.all(8.0),
                          child: Icon(Icons.abc,
                              color: Colors.blue, size: 46),
                        )
                      : Container()),
              Expanded(
                child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: TextField(
                    controller: messageInputController,
                    decoration: const InputDecoration(
                      border: InputBorder.none,
                      hintText: 'enter text',
                    ),
                    onChanged: (value) {
                      messageInputChanged();
                    },
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    ),
  );
}
英文:

The InputDecorator accepts a Widget? for the prefixIcon, however, it does not work with a Container(). That's strange.
If I replace your

prefixIcon: !showPrefixIcon ? Container() :  Padding(...)

with

prefixIcon: !showPrefixIcon ? SizedBox(height: 0.0, width: 0.0) :  Padding(...)

it works.
I honestly don't know why.


updated proposal:
Use:

prefixIcon: !showPrefixIcon ? null :  Padding(...)

And I just assume that you could then reasonably argue that this is ugly. Then, I fear, you have to change the way of doing it to something like this:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Container(
            height: 70.0,
            decoration: BoxDecoration(
                border: Border.all(
                  color: Colors.blue,
                ),
                borderRadius: const BorderRadius.all(Radius.circular(10))),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                AnimatedSwitcher(
                    duration: const Duration(milliseconds: 600),
                    transitionBuilder: (child, animation) =&gt; SizeTransition(
                        sizeFactor: animation,
                        axis: Axis.horizontal,
                        child: child),
                    child: showPrefixIcon
                        ? const Padding(
                            padding: EdgeInsets.all(8.0),
                            child: Icon(Icons.abc,
                                color: Colors.blue, size: 46),
                          )
                        : Container()),
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: TextField(
                      controller: messageInputController,
                      decoration: const InputDecoration(
                        border: InputBorder.none,
                        hintText: &#39;enter text&#39;,
                      ),
                      onChanged: (value) {
                        messageInputChanged();
                      },
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

huangapple
  • 本文由 发表于 2023年2月14日 03:00:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75440170.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定