如何向TextField Widget添加清除按钮

xia*_*oyu 33 flutter

有没有一种方法可以在Flutter中的TextField Widget中添加一个清除按钮?

喜欢这张图片的matrial设计指南: 在此输入图像描述

我发现在InputDecoration的suffixIcon中设置一个清晰的IconButton.这是正确的方法吗?

小智 28

        Container(
            margin: EdgeInsets.only(left: 16.0),
            child: TextFormField(
              controller: _username,
              decoration: InputDecoration(
                  hintText: '?????',
                  filled: true,
                  prefixIcon: Icon(
                    Icons.account_box,
                    size: 28.0,
                  ),
                  suffixIcon: IconButton(
                      icon: Icon(Icons.remove),
                      onPressed: () {
                        debugPrint('222');
                      })),
            ),
          ),
Run Code Online (Sandbox Code Playgroud)

使用iconButton

  • 要完成此示例,如果文本值为空,则将颜色设置为透明:`icon: Icon(Icons.cancel,color: _username.text.isNotEmpty ? Colors.grey : Colors.transparent )` (2认同)

Vil*_*abs 21

试试这个 -

final TextEditingController _controller = new TextEditingController();
Run Code Online (Sandbox Code Playgroud)
new Stack(
            alignment: const Alignment(1.0, 1.0),
            children: <Widget>[
              new TextField(controller: _controller,),
              new FlatButton(
                  onPressed: () {
                     _controller.clear();
                  },
                  child: new Icon(Icons.clear))
            ]
        )
Run Code Online (Sandbox Code Playgroud)

  • 这是错误的方法! (6认同)

jit*_*555 10

TextEditingController用于检查 Text 的当前状态,我们可以根据 Text 的可用性来决定是否可以显示取消图标。

  var _usernameController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Center(
          child: TextField(
            controller: _usernameController,
            onChanged: (text) {
              setState(() {});
            },
            decoration: InputDecoration(
                labelText: 'Username',
                suffixIcon: _usernameController.text.length > 0
                    ? IconButton(
                        onPressed: () {
                          _usernameController.clear();
                          setState(() {});
                        },
                        icon: Icon(Icons.cancel, color: Colors.grey))
                    : null),
          ),
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

输出:

在此输入图像描述


Met*_*ete 9

这是另一个答案,在@Vilokan Lab的答案上有所扩展,因为FlatButton的最小宽度为88.0,因此清除按钮根本没有与TextField右对齐,这对我而言并不是真正的做到。

因此,我继续制作自己的按钮类,并使用Stack进行应用,这是我的过程:

按钮类:

class CircleIconButton extends StatelessWidget {
final double size;
final Function onPressed;
final IconData icon;

CircleIconButton({this.size = 30.0, this.icon = Icons.clear, this.onPressed});

@override
Widget build(BuildContext context) {
  return InkWell(
    onTap: this.onPressed,
    child: SizedBox(
        width: size,
        height: size,
        child: Stack(
          alignment: Alignment(0.0, 0.0), // all centered
          children: <Widget>[
            Container(
              width: size,
              height: size,
              decoration: BoxDecoration(
                  shape: BoxShape.circle, color: Colors.grey[300]),
            ),
            Icon(
              icon,
              size: size * 0.6, // 60% width for icon
            )
          ],
        )));
  }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样将其InputDecoration应用于您的TextField:

var myTextField = TextField(
  controller: _textController,
  decoration: InputDecoration(
      hintText: "Caption",
      suffixIcon: CircleIconButton(
        onPressed: () {
          this.setState(() {
            _textController.clear();
          });
        },
      )),
  },
);
Run Code Online (Sandbox Code Playgroud)

为了得到这个:

未突出显示状态

在此处输入图片说明

突出显示/选定状态。

在此处输入图片说明

请注意,使用时此颜色是免费的suffixIcon


请注意,您也可以像这样将其堆叠在TextField中,但使用时不会获得自动着色suffixIcon

var myTextFieldView = Stack(
  alignment: Alignment(1.0,0.0), // right & center
  children: <Widget>[
    TextField(
      controller: _textController,
      decoration: InputDecoration(hintText: "Caption"),
    ),
    Positioned(
      child: CircleIconButton(
        onPressed: () {
          this.setState(() {
            _textController.clear();
          });
        },
      ),
    ),
  ],
);
Run Code Online (Sandbox Code Playgroud)


Jef*_*son 8

这是我的有效代码片段。

它的作用:如果文本字段值不为空,则仅显示清除按钮

class _MyTextFieldState extends State<MyTextField> {
  TextEditingController _textController;
  bool _wasEmpty;

  @override
  void initState() {
    super.initState();
    _textController = TextEditingController(text: widget.initialValue);
    _wasEmpty = _textController.text.isEmpty;
    _textController.addListener(() {
      if (_wasEmpty != _textController.text.isEmpty) {
        setState(() => {_wasEmpty = _textController.text.isEmpty});
      }
    });
  }

  @override
  void dispose() {
    _textController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextFormField(
          controller: _textController,
          decoration: InputDecoration(
            labelText: widget.label,
            suffixIcon: _textController.text.isNotEmpty
                ? Padding(
                    padding: const EdgeInsetsDirectional.only(start: 12.0),
                    child: IconButton(
                      iconSize: 16.0,
                      icon: Icon(Icons.cancel, color: Colors.grey,),
                      onPressed: () {
                        setState(() {
                          _textController.clear();
                        });
                      },
                    ),
                  )
                : null,
          ),);
...
Run Code Online (Sandbox Code Playgroud)


Tah*_*shi 6

在文本字段内添加图标.您必须在输入装饰中使用suffixIcon或prefixIcon.

TextFormField(
    autofocus: false,
    obscureText: true,
    decoration: InputDecoration(
       labelText: 'Password',
       suffixIcon: Icon(
                    Icons.clear,
                    size: 20.0,
                  ),
       border: OutlineInputBorder(
       borderRadius: BorderRadius.all(Radius.circular(0.0)),
     ),
      hintText: 'Enter Password',
      contentPadding: EdgeInsets.all(10.0),
    ),
  );
Run Code Online (Sandbox Code Playgroud)


Zul*_*qar 6

使用图标和清除按钮搜索TextField

import 'package:flutter/material.dart';

  class SearchTextField extends StatefulWidget{
    @override
    State<StatefulWidget> createState() {
      // TODO: implement createState
      return new SearchTextFieldState();
    }
  }

  class SearchTextFieldState extends State<SearchTextField>{
    final TextEditingController _textController = new TextEditingController();

    @override
    Widget build(BuildContext context) {
      // TODO: implement build
      return new Row(children: <Widget>[
        new Icon(Icons.search, color: _textController.text.length>0?Colors.lightBlueAccent:Colors.grey,),
        new SizedBox(width: 10.0,),
        new Expanded(child: new Stack(
            alignment: const Alignment(1.0, 1.0),
            children: <Widget>[
              new TextField(
                decoration: InputDecoration(hintText: 'Search'),
                onChanged: (text){
                  setState(() {
                    print(text);
                  });
                },
                controller: _textController,),
              _textController.text.length>0?new IconButton(icon: new Icon(Icons.clear), onPressed: () {
                setState(() {
                  _textController.clear();
                });
              }):new Container(height: 0.0,)
            ]
        ),),
      ],);
    }
  }
Run Code Online (Sandbox Code Playgroud)

搜索_1

搜索_2


Ben*_*eri 6

TextFormField(
                  controller:_controller
                  decoration: InputDecoration(
                    suffixIcon: IconButton(
                      onPressed: (){
                        _controller.clear();
                      },
                      icon: Icon(
                      Icons.keyboard,
                      color: Colors.blue,
                    ),
                    ),

                  ),
                )
Run Code Online (Sandbox Code Playgroud)


Cop*_*oad 6

输出:

在此处输入图片说明

创建一个变量

var _controller = TextEditingController();
Run Code Online (Sandbox Code Playgroud)

而你的TextField

TextField(
  controller: _controller,
  decoration: InputDecoration(
    hintText: "Enter a message",
    suffixIcon: IconButton(
      onPressed: () => _controller.clear(),
      icon: Icon(Icons.clear),
    ),
  ),
)
Run Code Online (Sandbox Code Playgroud)

  • 我想补充一点,如果“filled”属性设置为 true,则图标单击的飞溅效果将呈现在文本字段后面。为了避免这种情况,我发现的最简单的解决方案是用透明颜色的 Material 小部件包裹 IconButton 并剪辑它: ClipOval( child: Material( color: Colors.transparent, child: IconButton( ... ), )) (4认同)

Max*_*lin 6

不想走 StatefulWidget 路线。下面是一个使用 TextEditingController 和 StatelessWidget 的例子(提供者推送更新)。我将控制器保持在静态字段中。

class _SearchBar extends StatelessWidget {
  static var _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    var dictionary = Provider.of<Dictionary>(context);

    return TextField(
        controller: _controller,
        autofocus: true,
        onChanged: (text) {
          dictionary.lookupWord = text;
        },
        style: TextStyle(fontSize: 20.0),
        decoration: InputDecoration(
            border: InputBorder.none,
            hintText: 'Search',
            suffix: GestureDetector(
              onTap: () {
                dictionary.lookupWord = '';
                _controller.clear();
              },
              child: Text('x'),
            )));
  }
}
Run Code Online (Sandbox Code Playgroud)


gsm*_*gsm 6

TextField(
  decoration: InputDecoration(
    suffixIcon: IconButton(
      icon: Icon(
        Icons.cancel,
      ),
      onPressed: () {
        _controllerx.text = '';
      }
    ),
  )
)
Run Code Online (Sandbox Code Playgroud)

  • 在 StackOverflow 上添加关于为什么您的解决方案应该有效的解释是一个很好的做法。 (2认同)