So fügen Sie dem TextField-Widget eine Schaltfläche zum Löschen hinzu

74

Gibt es eine geeignete Möglichkeit, dem eine eindeutige Schaltfläche hinzuzufügen TextField?

Genau wie dieses Bild aus den Richtlinien für Materialdesign:

Geben Sie hier die Bildbeschreibung ein

Was ich gefunden habe, ist ein klares Zeichen IconButtonin den InputDecoration's suffixIcon. Ist das der richtige Weg?

Xiaoyu
quelle

Antworten:

99

Ausgabe:

Geben Sie hier die Bildbeschreibung ein

Erstellen Sie eine Variable

var _controller = TextEditingController();

Und dein TextField:

TextField(
  controller: _controller,
  decoration: InputDecoration(
    hintText: "Enter a message",
    suffixIcon: IconButton(
      onPressed: () => _controller.clear(),
      icon: Icon(Icons.clear),
    ),
  ),
)
CopsOnRoad
quelle
58
        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');
                      })),
            ),
          ),

benutze iconButton

赵 开元
quelle
38

Versuche dies -

final TextEditingController _controller = new TextEditingController();
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))
            ]
        )
Vilokan Labs
quelle
15

Hier ist eine weitere Antwort, die die Antwort von @Vilokan Lab etwas erweitert, was für mich nicht wirklich der Fall war, da FlatButton eine Mindestbreite von 88,0 hat und die Schaltfläche zum Löschen daher überhaupt nicht rechtsbündig mit dem TextField angezeigt wurde.

Also habe ich meine eigene Button-Klasse erstellt und diese mithilfe eines Stacks angewendet. Hier ist mein Prozess:

Tastenklasse:

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
            )
          ],
        )));
  }
}

Dann bewerben Sie sich wie InputDecorationfolgt auf Ihr TextField:

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

Um dies zu bekommen:

Nicht hervorgehobener Zustand

Geben Sie hier die Bildbeschreibung ein

Markierter / ausgewählter Zustand.

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass diese Färbung bei Verwendung kostenlos ist suffixIcon.


Beachten Sie, dass Sie es auch wie folgt in Ihr TextField stapeln können, aber nicht die automatische Färbung erhalten, die Sie erhalten, wenn Sie Folgendes verwenden 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();
          });
        },
      ),
    ),
  ],
);
Mete
quelle
10

Durchsuchen Sie TextField mit dem Symbol und der Schaltfläche zum Löschen

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,)
            ]
        ),),
      ],);
    }
  }

search_1

search_2

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

                  ),
                )
Benjith Kizhisseri
quelle
6

Hinzufügen eines Symbols innerhalb des Textfelds. Sie müssen SuffixIcon oder PrefixIcon in der Eingabedekoration verwenden.

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),
    ),
  );
Tahseen Quraishi
quelle
1
Wie erkenne ich einen Symbolklick, um den gesamten Text zu löschen? Erkennen Sie Klicks, indem Sie onTap implementieren, aber die Ansicht nicht neu zeichnen. muss setState () aufrufen, kann aber keinen Weg finden.
Hitesh Dhamshaniya
1
Sie können IconButton an das Suffixicon zurückgeben. Dadurch erhalten Sie ein onPressed-Ereignis. "SuffixIcon: IconButton (Symbol: Symbol (Icons.arrow_back), onPressed: () {},)"
Tahseen Quraishi
4

Ich wollte nicht die StatefulWidget-Route gehen. Hier ist ein Beispiel mit TextEditingController und StatelessWidget (wobei Anbieter Updates pushen). Ich halte den Controller im statischen Feld.

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'),
            )));
  }
}
Maxim Saplin
quelle
1

Hier ist ein Ausschnitt meines Codes, der funktioniert.

Was es tut: Nur die Schaltfläche Löschen anzeigen, wenn der Textfeldwert nicht leer ist

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,
          ),);
...
Jefferson Poe
quelle
0
IconButton(
              icon: Icon(Icons.clear_all),
              tooltip: 'Close',
              onPressed: () { 
              },
            )
Manikandan
quelle
0

Wenn Sie ein gebrauchsfertiges Widget möchten, das Sie einfach in eine Datei einfügen und dann über ein wiederverwendbares Element verfügen können, das Sie durch Einfügen von ClearableTextField () überall verwenden können , verwenden Sie diesen Code:

import 'package:flutter/material.dart';

class ClearableTexfield extends StatefulWidget {
  ClearableTexfield({
    Key key,
    this.controller,
    this.hintText = 'Enter text'
  }) : super(key: key);

  final TextEditingController controller;
  final String hintText;

  @override
  State<StatefulWidget> createState() {
    return _ClearableTextfieldState();
  }
}

class _ClearableTextfieldState extends State<ClearableTexfield> {
  bool _showClearButton = false;

  @override
  void initState() {
    super.initState();
    widget.controller.addListener(() {
      setState(() {
        _showClearButton = widget.controller.text.length > 0;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: widget.controller,
      decoration: InputDecoration(
        hintText: widget.hintText,
        suffixIcon: _getClearButton(),
      ),
    );
  }

  Widget _getClearButton() {
    if (!_showClearButton) {
      return null;
    }

    return IconButton(
      onPressed: () => widget.controller.clear(),
      icon: Icon(Icons.clear),
    );
  }
}

Weitere Erklärungen finden Sie auf dieser Seite:

https://www.flutterclutter.dev/flutter/tutorials/text-field-with-clear-button/2020/104/

Es baut ebenfalls auf IconButton auf, hat jedoch den Vorteil , dass die Schaltfläche zum Löschen nur angezeigt wird, wenn sich Text im Textfeld befindet.

Sieht aus wie das:

Geben Sie hier die Bildbeschreibung ein

Schnodderbalken
quelle
0
suffixIcon: IconButton(
  icon: Icon(
  Icons.cancel,
  ),
onPressed: () {
  _controllerx.text = '';
),
gsm
quelle
Bei StackOverflow empfiehlt es sich, eine Erklärung hinzuzufügen, warum Ihre Lösung funktionieren sollte.
Shree