简体   繁体   中英

Flutter. How to implement editable text field with DropDownButton?

I am trying to implement a TextField with DropDown menu, just like DropdownButtonFormField but with ability to edit it like ordinary text field. So user have options to fill the field by hand or to make a choice from drop down menu.

  1. DropdownButtonFormField - can't edit by hand, and can't set menu rounded corners

  2. TextFormField + DropdownButton as a suffix child. Seems good option but I cant set the suffix always visible, it disappears without focus!

  3. Row ( separate TextFormField + separate DropDownButton)linked with TextEditController, seems work, but how to REMOVE empty space from DropDownButton where usually value lives? (value is null so it is not visible but the empty space for it presents) and the common question is this acceptable workaround for my purpose..?

  4. PopupMenuButton - almost what I need, just button with menu, but this time it is not possible to set a max Height for drop down menu.

Unfortunately cant find clear and straightforward way to implement this. I hope I miss something. Any advice/help will be appreciated! Thanks in advance!

You can use the Visibility Widget in a stack . This is what I have managed to do

在此处输入图像描述


First you add a global variable to keep track of the visibility :
   late FocusNode myFocusNode = FocusNode();

  @override
  void initState() {
    super.initState();

    myFocusNode.addListener(_onFocusChange);
 
  }
  void _onFocusChange() {
    print("Focus: ${myFocusNode.hasFocus.toString()}");

    setState(() {
       isVisible=myFocusNode.hasFocus;
    });
   
  }

  @override
  void dispose() {
    // Clean up the focus node when the Form is disposed.
    myFocusNode.dispose();

    super.dispose();
  }

Then you add this to create a FocusNode and keep track of your textfield :

return Scaffold(

      body:  Column(
        children: [
          Expanded(
            flex :1,
            child: Container(
              color: Colors.yellow,
              child: Row(children: [
                    Expanded(child: TextField(focusNode: myFocusNode,)),Expanded(child: Container())
                  ],),
            ),
          ),
          Expanded(flex :9,child: Stack(children: [Column(
            children: [
              Expanded(flex:5 ,child: Visibility(visible: isVisible ,child: Container(
                color: Colors.black,
                child: Center(child: Text("This shows only if textfield has focus",style: TextStyle(color: Colors.yellow),)),),)),
              Expanded(flex : 5 ,child: Container())
            ],
          )],)),
        ],
      )   );

Finally you do something like this to create a similar structure as mine :

 return Scaffold( body: Column( children: [ Expanded( flex :1, child: Container( color: Colors.yellow, child: Row(children: [ Expanded(child: TextField(focusNode: myFocusNode,)),Expanded(child: Container()) ],), ), ), Expanded(flex :9,child: Stack(children: [Column( children: [ Expanded(flex:5 ,child: Visibility(visible: isVisible ,child: Container( color: Colors.black, child: Center(child: Text("This shows only if textfield has focus",style: TextStyle(color: Colors.yellow),)),),)), Expanded(flex : 5 ,child: Container()) ], )],)), ], ) );

You should use the Autocomplete-Widget:

https://api.flutter.dev/flutter/material/Autocomplete-class.html

By providing your own optionBuilder you can set your own suggestions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM