Code Monkey home page Code Monkey logo

searchable_dropdown's Introduction

searchable_dropdown

Widget to let the user search through a keyword string typed on a customizable keyboard in a single or multiple choices list presented as a dropdown in a dialog box or a menu.

Platforms

This widget has been successfully tested on iOS, Android and Chrome.

Examples

The following examples are extracted from the example project available in the repository.

Gallery

See code below.

Example name Demonstration
Single dialog Single dialog
Multi dialog Multi dialog
Single done button
dialog
Single done button dialog
Multi custom display
dialog
Multi custom display dialog
Multi select 3 dialog Multi select 3 dialog
Single menu Single menu
Multi menu Multi menu
Multi menu select
all/none
Multi menu select all or none
Multi dialog select
all/none without clear
Multi dialog select all or none without clear
Single dialog custom
keyboard
Single dialog custom keyboard
Single dialog object Single dialog object
Single dialog overflow Single dialog overflow
Single dialog readOnly Single dialog readOnly
Single dialog disabled Single dialog disabled

Code

Plugin usage

Add to your pubspec.yaml in the dependencies section:

  searchable_dropdown:

Get packages with command:

flutter packages get

Import:

import 'package:searchable_dropdown/searchable_dropdown.dart';

Call either the single choice or the multiple choice constructor.

Single choice constructor

Search choices Widget with a single choice that opens a dialog or a menu to let the user do the selection conveniently with a search.

factory SearchableDropdown.single({
    Key key,
    @required List<DropdownMenuItem<T>> items,
    @required Function onChanged,
    T value,
    TextStyle style,
    dynamic searchHint,
    dynamic hint,
    dynamic disabledHint,
    dynamic icon = const Icon(Icons.arrow_drop_down),
    dynamic underline,
    dynamic doneButton,
    dynamic label,
    dynamic closeButton = "Close",
    bool displayClearIcon = true,
    Icon clearIcon = const Icon(Icons.clear),
    Color iconEnabledColor,
    Color iconDisabledColor,
    double iconSize = 24.0,
    bool isExpanded = false,
    bool isCaseSensitiveSearch = false,
    Function searchFn,
    Function onClear,
    Function selectedValueWidgetFn,
    TextInputType keyboardType = TextInputType.text,
    Function validator,
    bool assertUniqueValue = true,
    Function displayItem,
    bool dialogBox = true,
    BoxConstraints menuConstraints,
    bool readOnly: false,
    Color menuBackgroundColor,
}
)
  • items with child: Widget displayed ; value: any object with .toString() used to match search keyword.
  • onChanged Function with parameter: value not returning executed after the selection is done.
  • value value to be preselected.
  • style used for the hint if it is given is String.
  • searchHint String|Widget|Function with no parameter returning String|Widget displayed at the top of the search dialog box.
  • hint String|Widget|Function with no parameter returning String|Widget displayed before any value is selected or after the selection is cleared.
  • disabledHint String|Widget|Function with no parameter returning String|Widget displayed instead of hint when the widget is displayed.
  • icon String|Widget|Function with parameter: value returning String|Widget displayed next to the selected item or the hint if none.
  • underline String|Widget|Function with parameter: value returning String|Widget displayed below the selected item or the hint if none.
  • doneButton String|Widget|Function with parameter: value returning String|Widget displayed at the top of the search dialog box.
  • label String|Widget|Function with parameter: value returning String|Widget displayed above the selected item or the hint if none.
  • closeButton String|Widget|Function with parameter: value returning String|Widget displayed at the bottom of the search dialog box.
  • displayClearIcon whether or not to display an icon to clear the selected value.
  • clearIcon Icon to be used for clearing the selected value.
  • iconEnabledColor Color to be used for enabled icons.
  • iconDisabledColor Color to be used for disabled icons.
  • iconSize for the icons next to the selected value (icon and clearIcon).
  • isExpanded can be necessary to avoid pixel overflows (zebra symptom).
  • isCaseSensitiveSearch only used when searchFn is not specified.
  • searchFn Function with parameters: keyword, items returning List as the list of indexes for the items to be displayed.
  • onClear Function with no parameter not returning executed when the clear icon is tapped.
  • selectedValueWidgetFn Function with parameter: item returning Widget to be used to display the selected value.
  • keyboardType used for the search.
  • validator Function with parameter: value returning String displayed below selected value when not valid and null when valid.
  • assertUniqueValue whether to run a consistency check of the list of items.
  • displayItem Function with parameters: item, selected returning Widget to be displayed in the search list.
  • dialogBox whether the search should be displayed as a dialog box or as a menu below the selected value if any.
  • menuConstraints BoxConstraints used to define the zone where to display the search menu. Example: BoxConstraints.tight(Size.fromHeight(250)) . Not to be used for dialogBox = true.
  • readOnly bool whether to let the user choose the value to select or just present the selected value if any.
  • menuBackgroundColor Color background color of the menu whether in dialog box or menu mode.

Multiple choice constructor

Search choices Widget with a multiple choice that opens a dialog or a menu to let the user do the selection conveniently with a search.

SearchableDropdown<T>.multiple(
{
    Key key,
    @required List<DropdownMenuItem<T>> items,
    @required Function onChanged,
    List<int> selectedItems: const [],
    TextStyle style,
    dynamic searchHint,
    dynamic hint,
    dynamic disabledHint,
    dynamic icon: const Icon(Icons.arrow_drop_down),
    dynamic underline,
    dynamic doneButton: "Done",
    dynamic label,
    dynamic closeButton: "Close",
    bool displayClearIcon: true,
    Icon clearIcon: const Icon(Icons.clear),
    Color iconEnabledColor,
    Color iconDisabledColor,
    double iconSize: 24.0,
    bool isExpanded: false,
    bool isCaseSensitiveSearch: false,
    Function searchFn,
    Function onClear,
    Function selectedValueWidgetFn,
    TextInputType keyboardType: TextInputType.text,
    Function validator,
    Function displayItem,
    bool dialogBox: true,
    BoxConstraints menuConstraints,
    bool readOnly: false,
    Color menuBackgroundColor,
}
)
  • items with child: Widget displayed ; value: any object with .toString() used to match search keyword.
  • onChanged Function with parameter: selectedItems not returning executed after the selection is done.
  • selectedItems indexes of items to be preselected.
  • style used for the hint if it is given is String.
  • searchHint String|Widget|Function with no parameter returning String|Widget displayed at the top of the search dialog box.
  • hint String|Widget|Function with no parameter returning String|Widget displayed before any value is selected or after the selection is cleared.
  • disabledHint String|Widget|Function with no parameter returning String|Widget displayed instead of hint when the widget is displayed.
  • icon String|Widget|Function with parameter: selectedItems returning String|Widget displayed next to the selected items or the hint if none.
  • underline String|Widget|Function with parameter: selectedItems returning String|Widget displayed below the selected items or the hint if none.
  • doneButton String|Widget|Function with parameter: selectedItems returning String|Widget displayed at the top of the search dialog box. Cannot be null in multiple selection mode.
  • label String|Widget|Function with parameter: selectedItems returning String|Widget displayed above the selected items or the hint if none.
  • closeButton String|Widget|Function with parameter: selectedItems returning String|Widget displayed at the bottom of the search dialog box.
  • displayClearIcon whether or not to display an icon to clear the selected values.
  • clearIcon Icon to be used for clearing the selected values.
  • iconEnabledColor Color to be used for enabled icons.
  • iconDisabledColor Color to be used for disabled icons.
  • iconSize for the icons next to the selected values (icon and clearIcon).
  • isExpanded can be necessary to avoid pixel overflows (zebra symptom).
  • isCaseSensitiveSearch only used when searchFn is not specified.
  • searchFn Function with parameters: keyword, items returning List as the list of indexes for the items to be displayed.
  • onClear Function with no parameter not returning executed when the clear icon is tapped.
  • selectedValueWidgetFn Function with parameter: item returning Widget to be used to display the selected values.
  • keyboardType used for the search.
  • validator Function with parameter: selectedItems returning String displayed below selected values when not valid and null when valid.
  • displayItem Function with parameters: item, selected returning Widget to be displayed in the search list.
  • dialogBox whether the search should be displayed as a dialog box or as a menu below the selected values if any.
  • menuConstraints BoxConstraints used to define the zone where to display the search menu. Example: BoxConstraints.tight(Size.fromHeight(250)) . Not to be used for dialogBox = true.
  • readOnly bool whether to let the user choose the value to select or just present the selected value if any.
  • menuBackgroundColor Color background color of the menu whether in dialog box or menu mode.

Example app usage

Clone repository:

git clone https://github.com/icemanbsi/searchable_dropdown.git

Go to plugin folder:

cd searchable_dropdown

Optionally enable web:

flutter config --enable-web

Create project:

flutter create .

To run automated tests:

flutter test

Optionally generate documentation:

pub global activate dartdoc
dartdoc

Go to example app folder:

cd example

To run web:

run -d chrome

To build web to folder build/web:

flutter build web

To run on a connected device:

flutter run

To build Android app to build/app/outputs/apk/release/app-release.apk:

flutter build apk

To build iOS app on Mac:

flutter build ios

Single dialog

      SearchableDropdown.single(
        items: items,
        value: selectedValue,
        hint: "Select one",
        searchHint: "Select one",
        onChanged: (value) {
          setState(() {
            selectedValue = value;
          });
        },
        isExpanded: true,
      ),

Multi dialog

      SearchableDropdown.multiple(
        items: items,
        selectedItems: selectedItems,
        hint: Padding(
          padding: const EdgeInsets.all(12.0),
          child: Text("Select any"),
        ),
        searchHint: "Select any",
        onChanged: (value) {
          setState(() {
            selectedItems = value;
          });
        },
        closeButton: (selectedItems) {
          return (selectedItems.isNotEmpty
              ? "Save ${selectedItems.length == 1 ? '"' + items[selectedItems.first].value.toString() + '"' : '(' + selectedItems.length.toString() + ')'}"
              : "Save without selection");
        },
        isExpanded: true,
      ),

Single done button dialog

      SearchableDropdown.single(
        items: items,
        value: selectedValue,
        hint: "Select one",
        searchHint: "Select one",
        onChanged: (value) {
          setState(() {
            selectedValue = value;
          });
        },
        doneButton: "Done",
        displayItem: (item, selected) {
          return (Row(children: [
            selected
                ? Icon(
                    Icons.radio_button_checked,
                    color: Colors.grey,
                  )
                : Icon(
                    Icons.radio_button_unchecked,
                    color: Colors.grey,
                  ),
            SizedBox(width: 7),
            Expanded(
              child: item,
            ),
          ]));
        },
        isExpanded: true,
      ),

Multi custom display dialog

      SearchableDropdown.multiple(
        items: items,
        selectedItems: selectedItems,
        hint: Padding(
          padding: const EdgeInsets.all(12.0),
          child: Text("Select any"),
        ),
        searchHint: "Select any",
        onChanged: (value) {
          setState(() {
            selectedItems = value;
          });
        },
        displayItem: (item, selected) {
          return (Row(children: [
            selected
                ? Icon(
                    Icons.check,
                    color: Colors.green,
                  )
                : Icon(
                    Icons.check_box_outline_blank,
                    color: Colors.grey,
                  ),
            SizedBox(width: 7),
            Expanded(
              child: item,
            ),
          ]));
        },
        selectedValueWidgetFn: (item) {
          return (Center(
              child: Card(
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(10),
                    side: BorderSide(
                      color: Colors.brown,
                      width: 0.5,
                    ),
                  ),
                  margin: EdgeInsets.all(12),
                  child: Padding(
                    padding: const EdgeInsets.all(8),
                    child: Text(item.toString()),
                  ))));
        },
        doneButton: (selectedItemsDone, doneContext) {
          return (RaisedButton(
              onPressed: () {
                Navigator.pop(doneContext);
                setState(() {});
              },
              child: Text("Save")));
        },
        closeButton: null,
        style: TextStyle(fontStyle: FontStyle.italic),
        searchFn: (String keyword, items) {
          List<int> ret = List<int>();
          if (keyword != null && items != null && keyword.isNotEmpty) {
            keyword.split(" ").forEach((k) {
              int i = 0;
              items.forEach((item) {
                if (k.isNotEmpty &&
                    (item.value
                        .toString()
                        .toLowerCase()
                        .contains(k.toLowerCase()))) {
                  ret.add(i);
                }
                i++;
              });
            });
          }
          if (keyword.isEmpty) {
            ret = Iterable<int>.generate(items.length).toList();
          }
          return (ret);
        },
        clearIcon: Icon(Icons.clear_all),
        icon: Icon(Icons.arrow_drop_down_circle),
        label: "Label for multi",
        underline: Container(
          height: 1.0,
          decoration: BoxDecoration(
              border:
                  Border(bottom: BorderSide(color: Colors.teal, width: 3.0))),
        ),
        iconDisabledColor: Colors.brown,
        iconEnabledColor: Colors.indigo,
        isExpanded: true,
      ),

Multi select 3 dialog

      SearchableDropdown.multiple(
        items: items,
        selectedItems: selectedItems,
        hint: "Select 3 items",
        searchHint: "Select 3",
        validator: (selectedItemsForValidator) {
          if (selectedItemsForValidator.length != 3) {
            return ("Must select 3");
          }
          return (null);
        },
        onChanged: (value) {
          setState(() {
            selectedItems = value;
          });
        },
        doneButton: (selectedItemsDone, doneContext) {
          return (RaisedButton(
              onPressed: selectedItemsDone.length != 3
                  ? null
                  : () {
                      Navigator.pop(doneContext);
                      setState(() {});
                    },
              child: Text("Save")));
        },
        closeButton: (selectedItems) {
          return (selectedItems.length == 3 ? "Ok" : null);
        },
        isExpanded: true,
      ),

Single menu

      SearchableDropdown.single(
        items: items,
        value: selectedValue,
        hint: "Select one",
        searchHint: null,
        onChanged: (value) {
          setState(() {
            selectedValue = value;
          });
        },
        dialogBox: false,
        isExpanded: true,
        menuConstraints: BoxConstraints.tight(Size.fromHeight(350)),
      ),

Multi menu

      SearchableDropdown.multiple(
        items: items,
        selectedItems: selectedItems,
        hint: "Select any",
        searchHint: "",
        doneButton: "Close",
        closeButton: SizedBox.shrink(),
        onChanged: (value) {
          setState(() {
            selectedItems = value;
          });
        },
        dialogBox: false,
        isExpanded: true,
        menuConstraints: BoxConstraints.tight(Size.fromHeight(350)),
      ),

Multi menu select all/none

      SearchableDropdown.multiple(
        items: items,
        selectedItems: selectedItems,
        hint: "Select any",
        searchHint: "Select any",
        onChanged: (value) {
          setState(() {
            selectedItems = value;
          });
        },
        dialogBox: false,
        closeButton: (selectedItemsClose) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              RaisedButton(
                  onPressed: () {
                    setState(() {
                      selectedItems.clear();
                      selectedItems.addAll(
                          Iterable<int>.generate(items.length).toList());
                    });
                  },
                  child: Text("Select all")),
              RaisedButton(
                  onPressed: () {
                    setState(() {
                      selectedItems.clear();
                    });
                  },
                  child: Text("Select none")),
            ],
          );
        },
        isExpanded: true,
        menuConstraints: BoxConstraints.tight(Size.fromHeight(350)),
      ),

Multi dialog select all/none without clear

      SearchableDropdown.multiple(
        items: items,
        selectedItems: selectedItems,
        hint: "Select any",
        searchHint: "Select any",
        displayClearIcon: false,
        onChanged: (value) {
          setState(() {
            selectedItems = value;
          });
        },
        dialogBox: true,
        closeButton: (selectedItemsClose) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              RaisedButton(
                  onPressed: () {
                    setState(() {
                      selectedItems.clear();
                      selectedItems.addAll(
                          Iterable<int>.generate(items.length).toList());
                    });
                  },
                  child: Text("Select all")),
              RaisedButton(
                  onPressed: () {
                    setState(() {
                      selectedItems.clear();
                    });
                  },
                  child: Text("Select none")),
            ],
          );
        },
        isExpanded: true,
      ),

Single dialog custom keyboard

      SearchableDropdown.single(
        items: Iterable<int>.generate(20).toList().map((i) {
          return (DropdownMenuItem(
            child: Text(i.toString()),
            value: i.toString(),
          ));
        }).toList(),
        value: selectedValue,
        hint: "Select one number",
        searchHint: "Select one number",
        onChanged: (value) {
          setState(() {
            selectedValue = value;
          });
        },
        dialogBox: true,
        keyboardType: TextInputType.number,
        isExpanded: true,
      ),

Single dialog object

      SearchableDropdown.single(
        items: ExampleNumber.list.map((exNum) {
          return (DropdownMenuItem(
              child: Text(exNum.numberString), value: exNum));
        }).toList(),
        value: selectedNumber,
        hint: "Select one number",
        searchHint: "Select one number",
        onChanged: (value) {
          setState(() {
            selectedNumber = value;
          });
        },
        dialogBox: true,
        isExpanded: true,
      ),

Single dialog overflow

      SearchableDropdown.single(
        items: [
          DropdownMenuItem(
            child: Text(
                "way too long text for a smartphone at least one that goes in a normal sized pair of trousers but maybe not for a gigantic screen like there is one at my cousin's home in a very remote country where I 
wouldn't want to go right now"),
            value:
                "way too long text for a smartphone at least one that goes in a normal sized pair of trousers but maybe not for a gigantic screen like there is one at my cousin's home in a very remote country where I 
wouldn't want to go right now",
          )
        ],
        value: "",
        hint: "Select one",
        searchHint: "Select one",
        onChanged: (value) {
          setState(() {
            selectedValue = value;
          });
        },
        dialogBox: true,
        isExpanded: true,
      ),

Single dialog readOnly

      SearchableDropdown.single(
        items: [
          DropdownMenuItem(
            child: Text(
                "one item"),
            value:
            "one item",
          )
        ],
        value: "one item",
        hint: "Select one",
        searchHint: "Select one",
        disabledHint: "Disabled",
        onChanged: (value) {
          setState(() {
            selectedValue = value;
          });
        },
        dialogBox: true,
        isExpanded: true,
        readOnly: true,
      ),

Single dialog disabled

      SearchableDropdown.single(
        items: [
          DropdownMenuItem(
            child: Text(
                "one item"),
            value:
            "one item",
          )
        ],
        value: "one item",
        hint: "Select one",
        searchHint: "Select one",
        disabledHint: "Disabled",
        onChanged: null,
        dialogBox: true,
        isExpanded: true,
      ),

Feature requests/comments/questions/bugs

Feel free to log your feature requests/comments/questions/bugs here: https://github.com/icemanbsi/searchable_dropdown/issues

Contributions

We would be happy to merge pull request proposals provided that:

  • they don't break the compilation
  • they pass the automated testing
  • they provide the relevant adaptations to documentation and automated testing
  • they bring value
  • they don't completely transform the code
  • they are readable (though, I enjoy https://www.ioccc.org/ as a contest full of curiosities)

Contributions and forks are very welcome!

In your pull request, feel free to add your line in the contributors section below:

Contributors

CI/CD

Continuous integration/deployment status: CI-CD

searchable_dropdown's People

Contributors

icemanbsi avatar lcuis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

searchable_dropdown's Issues

widget.value == null

I use your demo,i had this problen,
family: Roboto, size: 15.0, weight: 400, baseline: ideographic, decoration: TextDecoration.none, softWrap: wrapping at box width, overflow: clip):
'package:searchable_dropdown/searchable_dropdown.dart': Failed assertion: line 90 pos 12: 'widget.value == null ||
widget.items.where((DropdownMenuItem item) => item.value == widget.value).length == 1': is not true.

Error updating subsequent component

Dear sirs, I have a component that, after selecting an item of type object, loads a list into another subsequent component. The problem occurs when I change the top component and it does not clear the selected item in the subsequent component. How do I clean this selected item? Or is it really a bug?

Here is an excerpt from the code to exemplify

Top component

Container _buildTipoVeiculo() {
    return Container(
      transform: Matrix4.translationValues(0.0, -10.0, -10.0),
      child: Container(
        child: SearchableDropdown.single(
          items: tipoVeiculos,
          value: _anuncioData.tipoVeiculo,
          doneButton: "OK",
          label: _anuncioData.tipoVeiculo != null
              ? Container(
                  child: Text("Tipo de Veículo",
                      style:
                          TextStyle(color: Colors.teal[900], fontSize: 12.0)),
                  transform: Matrix4.translationValues(10.0, 20.0, 0.0))
              : null,
          hint: Padding(
            padding: const EdgeInsets.only(top: 4.0, bottom: 16.0),
            child: Text("Tipo de Veículo"),
          ),
          searchHint: "Selecione um item",
          closeButton: null,
          onChanged: (value) {
            setState(() {
              if (value != _anuncioData.tipoVeiculo) {
                _anuncioData.tipoVeiculo = value;
                _anuncioData.marca = null;
                initMarcas();
              }
            });
          },
          validator: _validateCampoObrigatorio,
          displayItem: (item, selected) {
            return (Row(children: [
              selected
                  ? Icon(
                      Icons.radio_button_checked,
                      color: Colors.grey,
                    )
                  : Icon(
                      Icons.radio_button_unchecked,
                      color: Colors.grey,
                    ),
              SizedBox(width: 7),
              Expanded(
                child: item,
              ),
            ]));
          },
          isExpanded: true,
        ),
      ),
    );
  }

Subsequent component

Container _buildMarca() {
    return Container(
      transform: Matrix4.translationValues(0.0, -10.0, -10.0),
      child: FutureBuilder<List<Marca>>(
          future: _futureMarcas,
          builder: (context, snapshot) {
            if (snapshot.hasError) print(snapshot.error);
            if (_anuncioData == null ||
                _anuncioData.tipoVeiculo == null ||
                snapshot.hasData) {
              return SearchableDropdown.single(
                items: convertDropDownMenuItemMarcas(snapshot),
                value: _anuncioData.marca,
                doneButton: "OK",
                label: _anuncioData.marca != null
                    ? Container(
                        child: Text("Marca",
                            style: TextStyle(
                                color: Colors.teal[900], fontSize: 12.0)),
                        transform: Matrix4.translationValues(10.0, 20.0, 0.0))
                    : null,
                hint: Padding(
                  padding: const EdgeInsets.only(bottom: 10.0),
                  child: Container(
                      child: Text("Marca"),
                      transform: Matrix4.translationValues(0.0, -2.0, 0.0)),
                ),
                searchHint: "Selecione um item",
                closeButton: null,
                onChanged: (value) {
                  if (value != _anuncioData.marca) {
                    setState(() {
                      _anuncioData.marca = value;
                      _anuncioData.modelo = null;
                      initModelos();
                    });
                  }
                },
                validator: _validateCampoObrigatorio,
                displayItem: (item, selected) {
                  return (Row(children: [
                    selected
                        ? Icon(
                            Icons.radio_button_checked,
                            color: Colors.grey,
                          )
                        : Icon(
                            Icons.radio_button_unchecked,
                            color: Colors.grey,
                          ),
                    SizedBox(width: 7),
                    Expanded(
                      child: item,
                    ),
                  ]));
                },
                isExpanded: true,
              );
            } else {
              return CircularProgressIndicator();
            }
          }),
    );
  }

Thanks.

Error After update ver to 1.1.2

after updating ver to 1.1.2, i can't run the app, because this error :

e: Supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath:
class io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding, unresolved supertypes: androidx.lifecycle.LifecycleOwner
class io.flutter.embedding.engine.FlutterEngine, unresolved supertypes: androidx.lifecycle.LifecycleOwner

e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.2\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (3, 28): Unresolved reference: NonNull
e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.2\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (19, 36): Unresolved reference: NonNull
e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.2\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (41, 30): Unresolved reference: NonNull
e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.2\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (41, 57): Unresolved reference: NonNull
e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.2\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (49, 38): Unresolved reference: NonNull

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':searchable_dropdown:compileDebugKotlin'.

Compilation error. See log for more details

how to solve this ? thank you for your hard work

Search not working with Arabic language

The search not working in Arabic and it's only searching by word.

I need to edit the search functionality to let it like this: ( as it's more accurate ) and working in Arabic words

_searchResults = items
            .where((faculty) => faculty.title.toLowerCase().indexOf(query) > -1)
            .toList();

instead of using contains() method

Update: It's working but it always searches in value field I need to let the search bar search in other fields instead of value

Can't close the dropdown button in menu mode

Hi, first of all thank you por this plug in.

I'm not able to close de dropdown button in menu mode(dialogbox false) if I haven't chosen any item.
Could you please help me with some work around?

The dropdown value is not updating since the lasts updates

I used to have a flutter application with this searchable dropdown and when the value was changed to null and setState() was called the dropdown would show the hint text. This is not happening any more.

So the problem is that even if I set value: null; the value still shows the previous selected value... sounds crazy.

Any guesses why? Could I downgrade somehow to the 1.1.0 version to it back working as it did?

Huge thanks!

Pere

Case insensitivity

Currently, the search widget is case sensitive. It would be better if all searches by default are case insensitive.

Model Class Support

I tried to use the package with a model class, but when I search, it doesn't appear in the list. Do you have a model example? Or does this plugin really not support it?

My code:

class FabricanteOleo {
  String nome;
  int id;

  FabricanteOleo({this.nome, this.id});

  FabricanteOleo.fromJson(json) {
    nome = json['nome'];
    id = json['id'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['nome'] = this.nome;
    data['id'] = this.id;
    return data;
  }
}

 _dropSearch() {
    return new SearchableDropdown<FabricanteOleo>(
      isCaseSensitiveSearch: true,
      items: listaFabricantes.map((fab){
        return DropdownMenuItem<FabricanteOleo>(
          child: new Text(fab.nome),
          value: fab,
        );
      }).toList(),
      value: fabricanteOleoSelecionado,
      hint: new Text('Select One'),
      searchHint: new Text(
        'Select One',
        style: new TextStyle(fontSize: 20),
      ),
      onChanged: (FabricanteOleo value) {
        setState(() {
          this.fabricanteOleoSelecionado = value;
        });
      },
    );

Captura de Tela 2020-02-05 às 20 06 28

Arabic Not working

Hello
I have gone through arabic search issue in (#17 ) , but still arabic search is not working
what I missed in my code?

SearchableDropdown.single(
                  isCaseSensitiveSearch: true,
                  items: data.map((item) {
                    return new DropdownMenuItem(
                    child : Directionality(
                    textDirection: TextDirection.rtl,
                    child: new Text(item['countryNameAr'].toString(), textAlign: TextAlign.right, textDirection: TextDirection.rtl), ),
                    value: item['countryCode'].toString(),
                    );
                    }).toList(),
                   value: _mySelection,
                  hint: "Select one",
                  searchHint: "Select one",
                  onChanged: (value) {
                    setState(() {
                      _mySelection = value;
                    });
                  },
                  isExpanded: true,
                  searchFn: (String keyword,  List<DropdownMenuItem> items) {
                    List<int> ret = List<int>();
                    if (keyword != null && items != null) {
                      keyword.split(" ").forEach((k) {
                        int i = 0;
                        items.forEach((item) {
                          if (keyword.isEmpty || (k.isNotEmpty &&
                              (item.value.countryNameAr.toString().toLowerCase().contains(k.toLowerCase()) ||
                                  item.value.countryCode.toString().contains(k)))) {
                            ret.add(i);
                          }
                          i++;
                        });
                      });
                    }
                    if(keyword.isEmpty){
                      ret = Iterable<int>.generate(items.length).toList();
                    }
                    return (ret);
                  },

                ),

whenever i select the dropdown value in this code cursor(pointer) move to the upper textfield . How to solve this problem??

Column(
children: [

            Padding(
              padding: const EdgeInsets.only(top: 14),
              child: new TextField(

                // maxLengthEnforced: true,
                keyboardType: TextInputType.multiline,
                controller: controller1,
                decoration: new InputDecoration(
                  // contentPadding: EdgeInsets.symmetric(vertical: 26,horizontal: 10),
                    border: OutlineInputBorder(),
                    hintText: "Add Task name Only",
                    labelText: "Add Task name only"
                ),
              ),
            ),
            new SizedBox(
                height:6
            ),

            Column(
              children: <Widget>[

                Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[
                    new Text("Select Product:", style: new TextStyle(fontSize: 12),),
                  ],
                ),

                Container(

                  height: 50,
                  width: MediaQuery.of(context).size.width,
                  decoration: ShapeDecoration(

                    shape: RoundedRectangleBorder(

                      side: BorderSide(width: 1.0, style: BorderStyle.solid, color: Colors.blue),
                      borderRadius: BorderRadius.all(Radius.circular(5.0)),
                    ),
                  ),
                  child: Padding(
                    padding: const EdgeInsets.symmetric(horizontal:10.0),
                    child: StatefulBuilder(
                      //stream: null,
                        builder: (BuildContext context, StateSetter setState) {
                          /*  return  DropdownButton<String>(
                            //  hint: Text('Project'),
                              value:applicationDropDown,
                              isExpanded: true,

                              // style: Theme.of(context).textTheme.title,
                              //  icon: Icon(Icons.arrow_drop_down,color: Colors.lightBlue,),

                              onChanged: (String newValue) {
                                setState(() {
                                  applicationDropDown = newValue;
                                });


                              },
                              items: applicationList.cast<String>()

                                  .map<DropdownMenuItem<String>>((String value) {
                                return DropdownMenuItem<String>(
                                  value: value,
                                  child: Text(value),

                                );
                              })
                                  .toList()
                          );        */

                          return SearchableDropdown.single(
                            items: applicationList.cast<String>()

                                .map<DropdownMenuItem<String>>((String value) {
                              return DropdownMenuItem<String>(
                                value: value,
                                child: Text(value, ),

                              );
                            })
                                .toList(),
                            value: applicationDropDown,
                            hint: "Select one",
                            searchHint: "Select one",
                            onChanged: (value) {
                              setState(() {
                                applicationDropDown = value;
                              });
                            },
                            isExpanded: true,
                            // label: "Select Project",

                            selectedValueWidgetFn: (item) {
                              return Container(
                                  transform: Matrix4.translationValues(-10,0,0),
                                  alignment: Alignment.centerLeft,
                                  child: (Text(item.toString())));
                            },

                            // style: Theme.of(context).textTheme.title,
                            displayClearIcon: false,

                          );
                        }
                    ),
                  ),
                ),
              ],
            ),


            Padding(
              padding: const EdgeInsets.only(top:7.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: <Widget>[
                  Column(
                    //  mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      new Text("Select Customer:", style: new TextStyle(fontSize: 12),),

                      Container(

                        height: 50,
                        width: MediaQuery.of(context).size.width/2,
                        decoration: ShapeDecoration(

                          shape: RoundedRectangleBorder(

                            side: BorderSide(width: 1.0, style: BorderStyle.solid, color: Colors.blue),
                            borderRadius: BorderRadius.all(Radius.circular(5.0)),
                          ),
                        ),
                        child: Padding(
                          padding: const EdgeInsets.symmetric(horizontal:10.0),
                          child: StatefulBuilder(
                            //stream: null,
                              builder: (BuildContext context, StateSetter setState) {
                                return SearchableDropdown.single(
                                  items: projectList.cast<String>()

                                      .map<DropdownMenuItem<String>>((String value) {
                                    return DropdownMenuItem<String>(
                                      value: value,
                                      child: Text(value, ),

                                    );
                                  })
                                      .toList(),
                                  value: projectDropDown,
                                  hint: "Select one",
                                  searchHint: "Select one",
                                  onChanged: (value) {
                                    setState(() {
                                      projectDropDown = value;
                                    });
                                  },
                                  isExpanded: true,
                                  // label: "Select Project",

                                  selectedValueWidgetFn: (item) {
                                    return Container(
                                        transform: Matrix4.translationValues(-10,0,0),
                                        alignment: Alignment.centerLeft,
                                        child: (Text(item.toString())));
                                  },


                                  // style: Theme.of(context).textTheme.title,
                                  displayClearIcon: false,

                                );
                              }
                          ),
                        ),
                      ),
                    ],

in this code whenever i select any dropdown value cursor move to the add task textfiled. Is there any way to solve this problem. SO that cursor do not move to the textfiled again and again.

will be thankful for your help

Should be able to implement queryBuilder

Instead of filter value from DropdownMenuItem, I think it is better to add query builder which allow user to customize any filter list. For example:

        SearchableDropdown(
              dataList: operators,
              queryBuilder: (String keyword, List<OperatorModel> list) {
                List<int> shownIndexes = [];
                int i = 0;
                list.forEach((item) {
                  if(keyword.isEmpty || item.opeCode.toLowerCase().contains(keyword.trim().toLowerCase())
                      || item.opeName.toLowerCase().contains(keyword.trim().toLowerCase())
                      || item.opeNameEn.toLowerCase().contains(keyword.trim().toLowerCase())){
                    shownIndexes.add(i);
                  }
                  i++;
                });
                return shownIndexes;
              },
              items: operators.map((operator) {
                return DropdownMenuItem<int>(
                  child: Text(operator.opeCode + "-" + operator.opeName),
                  value: operator.opeId
                ); 
              }).toList(),
              value: selectedOperatorId,
              hint: new Text('Select One'),
              searchHint: new Text('Select One', style: new TextStyle(fontSize: 20)),
              onChanged: (value) {
                setState(() {
                  selectedOperatorId = value;
                });
              },
              isExpanded: true,
            )

Search not working

I have using searchable_dropdown lib, every thing working but searching option not working properly.I am sharing code with some screenshots, lease check help me.

Container(
padding: EdgeInsets.all(10.0),
child: SearchableDropdown.single(
items: _dropdownMenuItemsCamp,
value: selectCamp,
displayClearIcon: false,
isCaseSensitiveSearch: true,
hint: "Select Compaign Type *",
label: Text(
"Select Compaign Type *",
style: TextStyle(color: Colors.black54),
),
searchHint: "Select Compaign Type *",
onChanged: (value) {
setState(() {
selectCamp = value;
});
campType = selectCamp.generalID;
},
underline: Container(
height: 1.0,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.black38, width: 1.0))),
),
searchFn: (String keyword, items) {
List ret = List();
if (keyword != null &&
items != null &&
keyword.isNotEmpty) {
keyword.split(" ").forEach((k) {
int i = 0;
items.forEach((item) {
if (k.isNotEmpty &&
(item.value
.toString()
.toLowerCase()
.contains(k.toLowerCase()))) {
ret.add(i);
}
i++;
});
});
}
if (keyword.isEmpty) {
ret = Iterable.generate(items.length).toList();
}
return (ret);
},
isExpanded: true,
),
)

Screenshot_2020-04-11-08-50-56-080_worldjobsnews com flutter_app
Screenshot_2020-04-11-08-50-49-921_worldjobsnews com flutter_app

Disabled/Read Only Functionality

Is there any way to disable the dropdown? I noticed the disabled hint but no way to disable the dropdown itself.

Case:
I have a screen with several dropdowns thats reused in multiple places. Sometimes, I need to show whats selected in one dropdown and maintain that value without letting the user change it.

TextStyle does not apply to searchbox

Supplied a text style however this is not being passed through and picked up in the searchbox leading to large dropdown items but a tiny searchbox.
Screenshot 2020-03-31 at 09 34 34

using doneButton, selecting Items does not close the menu dropdown

Hi, I was using the SearchableDropdown single menu variant and had some questions.

I'd like to add a button that closes the menu and activates a callback (to open a dialog that enables the user to add a new option to the dropdown list), but passing a widget to the closeButton field in the constructor made it so that clicking the button no longer closed the menu dropdown.

I thought that using the doneButton for closing the menu dropdown might be an answer, but then clicking on an item did not close the dropdown anymore (which makes sense, that looks like the whole point of the doneButton anyway)

I'd like to know if and how I could achieve having two buttons on the dropdown menu, one that closes without needing to select an option (for when there is no option to be selected yet) and another that fires a callback passed on the constructor (and closes the dropdown menu also)

Related code below:

SearchableDropdown.single(
            hint: 'Selecione seu paciente',
            dialogBox: false,
            isExpanded: true,
            menuConstraints: BoxConstraints.tight(Size.fromHeight(350)),
            items: optionsList,
            onChanged: (value) {
              BlocProvider.of<NewSchedulingBloc>(context).add(SchedulingFormChanged(value));
            },
            searchHint: 'Digite o nome do seu paciente',
            closeButton: (selectedItemsClose){
              return Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  FlatButton(
                    onPressed: () => newPatientCallback(),
                    child: Text('Novo Paciente'),
                  ),
                  FlatButton(
                    onPressed: () => pop(), // =>Does not pop or close the dropdown menu at all...
                    child: Text('Novo Paciente'),
                  ),
                ],
              );
            },
           doneButton: 'Fechar'
          )

Thanks

Search Box fails to render screen in landscape mode

  • I've encountered a problem to render my search box in landscape mode.
  • I believe this occur because the keyboard fills the whole space that should belong to the list of items.
  • How can I fix this?
  • Is there any way to set a minimum height to search box with the list of items?

Screenshot

Error if removing from `items` the currently selected `value`

If attempting to remove from the items the currently selected value, a RangeError will be thrown.
A very small app to demonstrate this is the following. If you select the last item and then attempt to remove it from the items (clicking the remove last item button) the RangeError will be thrown.

import 'package:flutter/material.dart';
import 'package:searchable_dropdown/searchable_dropdown.dart';

void main() {
  runApp(App());
}

class App extends StatefulWidget {
  App();

  @override
  AppState createState() => AppState();
}

class AppState extends State<App> {
  List<String> _items = ['1', '2', '3'];
  String _selected = '3';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: 'TestApp',
        home: Material(child: Column(
          children: <Widget>[
            RaisedButton(child: Text('Remove last Item'),onPressed: () => setState(() => _items.removeLast())),
            SearchableDropdown(items: _items.map((e) => DropdownMenuItem(value: e, child: Text(e))).toList(),
            value: _selected, onChanged: (e) => setState(() => _selected = e))
          ],
        )
      )
    );
  }
}

Overflow with long text

Hi,

I tried using your dropdown in my app (two side-by-side), but both of them are overflowing if the text is too long (this was not happening with the DropdownButtonFormField, etc. that I was using before). Here is a screenshot:

searchableDropDownOverflowIssue

Attached is a modified version of your main.dart sample file (renamed to main.txt so that I could attach it).

If you could fix this, it would be great - this is the best drop-down component that I have found so far, apart from this issue.

main.txt

Build failed when using searchable_dropdown

I have used the searchable dropdown in one of my pages. My application is working fine in debug mode so I can run it on an emulator. But I'm getting my build failed when trying to build the apk using "flutter build apk" command.

Here is the error log I'm getting.

e: C:\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.3\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (3, 28): Unresolved reference: NonNull
e: C:\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.3\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (19, 36): Unresolved reference: NonNull
e: C:\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.3\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (41, 30): Unresolved reference: NonNull
e: C:\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.3\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (41, 57): Unresolved reference: NonNull
e: C:\flutter.pub-cache\hosted\pub.dartlang.org\searchable_dropdown-1.1.3\android\src\main\kotlin\bsi\iceman\searchable_dropdown\SearchableDropdownPlugin.kt: (49, 38): Unresolved reference: NonNull

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':compileReleaseKotlin'.

Compilation error. See log for more details

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

BUILD FAILED in 2s

The plugin searchable_dropdown could not be built due to the issue above.

flutter doctor -v output

[√] Flutter (Channel stable, v1.12.13+hotfix.8, on Microsoft Windows [Version 10.0.18363.752], locale en-US)
• Flutter version 1.12.13+hotfix.8 at C:\flutter
• Framework revision 0b8abb4724 (8 weeks ago), 2020-02-11 11:44:36 -0800
• Engine revision e1e6ced81d
• Dart version 2.7.0

[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
• Android SDK at C:\Users\tharindu.s.GEVEO\AppData\Local\Android\Sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-29, build-tools 29.0.3
• ANDROID_HOME = C:\Users\tharindu.s.GEVEO\AppData\Local\Android\Sdk
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)
• All Android licenses accepted.

[!] Android Studio (version 3.6)
• Android Studio at C:\Program Files\Android\Android Studio
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
• Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

[√] VS Code (version 1.43.2)
• VS Code at C:\Users\tharindu.s.GEVEO\AppData\Local\Programs\Microsoft VS Code
• Flutter extension version 3.9.1

[√] VS Code, 64-bit edition
• VS Code at C:\Program Files\Microsoft VS Code
• Flutter extension version 3.9.1

[√] Connected device (1 available)
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)

! Doctor found issues in 1 category.

Hello Search option not working

Hello sir i have used your provided solution and the search still not working

import 'package:flutter/material.dart';
// import 'package:foodfromforeign1/models/country.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:searchable_dropdown/searchable_dropdown.dart';

void main() => runApp( MyApp());

class Country{
  String name;
  int id;
  Country(this.name,this.id);
  toString(){
    return(name);
  }
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return  MaterialApp(
      title: 'Flutter Demo',
      theme:  ThemeData(
        primarySwatch: Colors.red,
      ),
      home:  MyHomePage(title: 'Users'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() =>  _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

static final String countriesJson = '[{"id":0,"name":"Afghanistan"},{"id":1,"name":"Albania"},{"id":2,"name":"Algeria"},{"id":3,"name":"Angola"}]';
List<Country> countries;
List<DropdownMenuItem<Country>> countriesDropdownItems;
Country selectedCountry;


    @override
  void initState() {
    super.initState();
   countries=(jsonDecode(countriesJson) as List<dynamic>).map<Country>((e) => Country(e['name'],e['id'])).toList();
    countriesDropdownItems = countries.map<DropdownMenuItem<Country>>((e) => DropdownMenuItem(child:Text(e.name),value:e,)).toList();
    super.initState();
  }

@override
  Widget build(BuildContext context) {
    return  Scaffold(
      appBar:  AppBar(
        title:  Text(widget.title),
      ),
      body:Container(
          padding: EdgeInsets.symmetric(horizontal: 20, vertical: 30),
        child:Column(
         children: <Widget>[
            SearchableDropdown.single(
        items: countriesDropdownItems,
        value: selectedCountry,
        hint: "Select one country",
        searchHint: "Select one country",
        onChanged: (value) {
          setState(() {
            selectedCountry = value;
          });
        },
        isExpanded: true,
      )
         ],

        ),  
      


        
      ),
    );
  
  }
}


How to Search data from api list

here is my data list from api


  Future<String> getSWData() async {
    var res = await http .get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
    var resBody = json.decode(res.body);

    setState(() {
      data = resBody;
    });

    return "Sucess";
  }
`
```
and here is my dropdown 

 ```
 children: <Widget>[
             SearchableDropdown.single(
             hint:Text("Select Country"),
              isExpanded: true,
          items: data.map((item) {
            return  DropdownMenuItem(
             
              child:  Text(item['name']),
              value: item['id'].toString(),
            );
      
          }).toList(),
          onChanged: (newVal) {
            setState(() {
              _countryname = newVal;
              city.clear();
              _myState=null;
              this.getCity(int.parse(_countryname));
            });
          },
          value:_countryname,
        ),
         ],
```

it's load data from api but when i search i m not getting search data is there is any extra step for search? the package should be dynamic like jquery select2

Using "searchable_dropdown" causes application build to fail

I tested this library in flutter and it was working great yesterday. Today I opened the project to continue working on it, but the application no longer builds. I get the following error when I try to debug the project on simulator.

If I remove searchable_dropdown dependency and replace the code with dart Dropdown, application starts and everything works.

I have made no changes as of yesterday. I already tried clearing builds and restarting the machine.

Here is how i use the library

  List<String> _items = ['aaaaaaa', 'bbbbbbb', 'ccccccc', 'dddddd'];
  String _selectedItem;
.
.
.
  SearchableDropdown.single(
    items: _items.map((location) {
      return DropdownMenuItem(
        child: new Text(location),
        value: location,
      );
    }).toList(),
    value: _selectedItem,
    hint: Text('Please select an Item'),
    searchHint: "Select one",
    onChanged: (value) {
      setState(() {
        _selectedItem = value;
      });
    },
    isExpanded: true,
  ),
.
.
.

Here is the error log I'm seeing, while using the version -> searchable_dropdown: ^1.1.3

Launching lib/main.dart on iPhone 11 in debug mode...
Running Xcode build...
Xcode build done.                                           15.9s
Failed to build iOS app
Error output from Xcode build:
↳
    ** BUILD FAILED **


Xcode's output:
↳
    === BUILD TARGET Runner OF PROJECT Runner WITH CONFIGURATION Debug ===
    ld: warning: Could not find or use auto-linked library 'swiftCoreFoundation'
    ld: warning: Could not find or use auto-linked library 'swiftCompatibility50'
    ld: warning: Could not find or use auto-linked library 'swiftObjectiveC'
    ld: warning: Could not find or use auto-linked library 'swiftCore'
    ld: warning: Could not find or use auto-linked library 'swiftQuartzCore'
    ld: warning: Could not find or use auto-linked library 'swiftCoreGraphics'
    ld: warning: Could not find or use auto-linked library 'swiftDarwin'
    ld: warning: Could not find or use auto-linked library 'swiftUIKit'
    ld: warning: Could not find or use auto-linked library 'swiftFoundation'
    ld: warning: Could not find or use auto-linked library 'swiftCoreImage'
    ld: warning: Could not find or use auto-linked library 'swiftCompatibilityDynamicReplacements'
    ld: warning: Could not find or use auto-linked library 'swiftMetal'
    ld: warning: Could not find or use auto-linked library 'swiftDispatch'
    ld: warning: Could not find or use auto-linked library 'swiftCoreMedia'
    ld: warning: Could not find or use auto-linked library 'swiftCoreAudio'
    ld: warning: Could not find or use auto-linked library 'swiftSwiftOnoneSupport'
    Undefined symbols for architecture x86_64:
      "value witness table for Builtin.UnknownObject", referenced from:
          full type metadata for searchable_dropdown.SwiftSearchableDropdownPlugin in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "__swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements", referenced from:
          __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements_$_searchable_dropdown in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
         (maybe you meant: __swift_FORCE_LOAD_$_swiftCompatibilityDynamicReplacements_$_searchable_dropdown)
      "_swift_allocObject", referenced from:
          @objc searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "static (extension in Foundation):Swift.String._unconditionallyBridgeFromObjectiveC(__C.NSString?) -> Swift.String", referenced from:
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "static Swift.String.+ infix(Swift.String, Swift.String) -> Swift.String", referenced from:
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_unknownObjectRelease", referenced from:
          static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          @nonobjc __C.FlutterMethodChannel.__allocating_init(name: Swift.String, binaryMessenger: __C.FlutterBinaryMessenger) -> __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          @objc static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          reabstraction thunk helper from @escaping @callee_unowned @convention(block) (@unowned Swift.AnyObject?) -> () to @escaping @callee_guaranteed (@in_guaranteed Any?) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_release", referenced from:
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          ___swift_destroy_boxed_opaque_existential_0 in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          @objc searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_deallocObject", referenced from:
          l_objectdestroy in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_retain", referenced from:
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_unknownObjectRetain", referenced from:
          @objc static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "Swift._bridgeAnythingToObjectiveC<A>(A) -> Swift.AnyObject", referenced from:
          reabstraction thunk helper from @escaping @callee_unowned @convention(block) (@unowned Swift.AnyObject?) -> () to @escaping @callee_guaranteed (@in_guaranteed Any?) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "(extension in Foundation):Swift.String._bridgeToObjectiveC() -> __C.NSString", referenced from:
          @nonobjc __C.FlutterMethodChannel.__allocating_init(name: Swift.String, binaryMessenger: __C.FlutterBinaryMessenger) -> __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_getObjCClassFromMetadata", referenced from:
          @nonobjc __C.FlutterMethodChannel.__allocating_init(name: Swift.String, binaryMessenger: __C.FlutterBinaryMessenger) -> __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "type metadata for Swift.String", referenced from:
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "__swift_FORCE_LOAD_$_swiftCompatibility50", referenced from:
          __swift_FORCE_LOAD_$_swiftCompatibility50_$_searchable_dropdown in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
         (maybe you meant: __swift_FORCE_LOAD_$_swiftCompatibility50_$_searchable_dropdown)
      "_swift_getObjCClassMetadata", referenced from:
          type metadata accessor for __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          @objc static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_bridgeObjectRelease", referenced from:
          @nonobjc __C.FlutterMethodChannel.__allocating_init(name: Swift.String, binaryMessenger: __C.FlutterBinaryMessenger) -> __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_getObjectType", referenced from:
          static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "_swift_getInitializedObjCClass", referenced from:
          type metadata accessor for __C.FlutterMethodChannel in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          type metadata accessor for searchable_dropdown.SwiftSearchableDropdownPlugin in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
      "Swift.String.init(_builtinStringLiteral: Builtin.RawPointer, utf8CodeUnitCount: Builtin.Word, isASCII: Builtin.Int1) -> Swift.String", referenced from:
          static searchable_dropdown.SwiftSearchableDropdownPlugin.register(with: __C.FlutterPluginRegistrar) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
          searchable_dropdown.SwiftSearchableDropdownPlugin.handle(_: __C.FlutterMethodCall, result: (Any?) -> ()) -> () in libsearchable_dropdown.a(SwiftSearchableDropdownPlugin.o)
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

Could not build the application for the simulator.
Error launching application on iPhone 11.

Any suggestions, how i could resolve this problem?

Searchable dropDown value is changing only once in stateful widget in flutter

Hi, my problem is when i try to select value in searchable dropdown second time then it is not changing remaining same as that in case of ist change , but i can select different value after clearing the value .

code:

SearchableDropdown.single(
items: widget.projectList.cast()

                                      .map<DropdownMenuItem<String>>((String value) {
                                    return DropdownMenuItem<String>(
                                      value: value,
                                      child: Text(value),

                                    );
                                  })
                                      .toList(),
                                  value: dropDownValue,
                                  hint: "Select one",
                                  searchHint: "Select one",
                                  onChanged: (value) {
                                    setState(() {
                                      dropDownValue = value;
                                    });
                                  },
                                  isExpanded: true,
                                  // label: "Select Project",
                                  selectedValueWidgetFn: (item) {
                                    return Container(
                                        transform: Matrix4.translationValues(-10,0,0),
                                        alignment: Alignment.centerLeft,
                                        child: (Text(item.toString())));
                                  },


                                  // style: Theme.of(context).textTheme.title,
                               //   displayClearIcon: false,

                                );

and this code is working perfect in stateless widget but problem coming in stateful widget.

i will be thankful for your solution

Can't clear selected value

How to clear the field in which the selected item is displayed, since it does not work through the “Tvalue” field, I do not know what to do? the field is cleared only by pressing the button the icon button into the widget.

keyboard always show up.

Hi,
first of all, let me thank the developer for this great and useful flutter package.

The keyboard seems to always show up when the dropdownMenu button is pressed. Can it be possible to only show the keyboard when the user presses the search input TextField?

I took a look at the package's code and it seems that autofocus: true is calling the keyboard, right? How to avoid this?

Thanks,
Ricardo

Flutter fails to build (Bad State Element) when using validator method of SearchableDropdown.single widget

Flutter doesn't build my application when I run. It returns the following:-
Error waiting for a debug connection: Bad state: No element

Flutter doctor:-

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, v1.12.13+hotfix.9, on Microsoft Windows [Version 10.0.18362.720], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[√] Android Studio (version 3.6)
[√] VS Code, 64-bit edition (version 1.43.1)
[√] Connected device (1 available)

• No issues found!

The application fails to build only when I add the 'validator:' attribute to the SearchableDropdown.single() widget. I guess the problem is that the SearchableDropdown is validating on the build and not when the validate() method of fomKey.currentState is called. Is there any workaround for this. Please help as this is for a time-sensitive project.

To help anyone reading this issue understand the code that is causing an issue, I've included the widget inside which I'm calling the SearchableDropdown. It is wrapped in a FutureBuilder widget as I call an API to return a list of all countries and to consequently build a List<DropdownMenuItem>, which is passed into the 'items:' attribute of SearchableDropdown.single().

FutureBuilder<List<dynamic>>(
  future: _fetchCountries,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      List<String> countrylist = [];
      List<DropdownMenuItem<String>> countries;
      for (var i = 0; i < snapshot.data.length; i++) {
        countrylist.add(snapshot.data[i]['name']);
      }
      countries = countrylist.map((String value) {
        return new DropdownMenuItem<String>(
          value: value,
          child: Text(
            value,
            style: TextStyle(fontSize: 16),
          ),
        );
      }).toList();
      return SearchableDropdown.single(
          //menuConstraints: BoxConstraints.tight(Size.fromHeight(350)),
          dialogBox: true,
          menuBackgroundColor: Colors.white,
          icon: Icon(
            Icons.arrow_drop_down,
            size: 25,
            color: Colors.white,
          ),
          items: countries,
          style: TextStyle(color: Colors.white),
          hint: Padding(
            padding: const EdgeInsets.only(left: 0, right: 0, top: 0, bottom: 15),
            child: Text(
              "Country",
              style: TextStyle(color: Colors.white, fontSize: 16),
            ),
          ),
          value: _country,
          searchHint: "Select a country",
          onChanged: (value) {
            setState(() {
              _country = value;
            });
          },
          isExpanded: true,
          validator: (value) {
            if (value == null) {
              return 'Select a country';
            }
            return null;
          });
    } else if (snapshot.hasError) {
      return Text("${snapshot.error}");
    }
    return CircularProgressIndicator();
  },
),

If anybody can suggest any other methods of validating the SearchableDropdown.single without running into the error, it would be well appreciated.

Dropdown not working after deploy

Hi, I was working in local and worked perfectly, but I deployed my app to Firebase Hosting and the dropdown stopped working in all browsers. I have no idea what could be the problem.

Thanks in advance,

Triggering the Selection Dialog from another widget

I'd loved how this widget works but would need the option to trigger the Selection Dialog from a button from my own layout. I could use the callOnPop to handle the selected behavior but I'm not sure how to trigger the Dialog with the SearchableDropdown visibility set to false.
Is there any suggestion in order to use just the Dialog, without the Search field?

Asynchronous Search with API [FEATURE]

This is the best plugin I could find for searchable dropdowns in Flutter but I would like to suggest a feature in where the user search in the input, then the data on the items list changes as well base on the data from a backend / API. That would be great.

If this is available or there is a way to implement this I might need an example, I'm new to Flutter.

Thank you.

Return old value after first select.

Current API Version
searchable_dropdown: ^1.1.3

Flutter Doctor

[✓] Flutter (Channel stable, v1.12.13+hotfix.9, on Mac OS X 10.15.3 19D76, locale en-KH)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 11.4)
[✓] Android Studio (version 3.4)
[✓] VS Code (version 1.44.2)
[✓] Connected device (2 available)

• No issues found!

[Note: The problem is not 100% occurred, but mostly it happens on iOS below 13 and also Android Emulator (API R)]

The problem is

  1. when we first launch the app and selected the value from the dropdown, it returns the correct value back. (exp: Select A and it return A)
  2. But when I try to select a new value [B] from dropdown again, it returns the old value of [A] instead.

It sounds weird, but the problem sometimes disappears when I tried to clean the project a few times.

My BaseDropDownTextField class.
BaseDropDownTextField.log

Issue when we define init value

when I set the value on value param then on change method returning me the same value instead of new value which I have selected.

After selecting sropdown data, showing left side space

I used below code, but showing some garbage data/
Uploading Screenshot_2020-04-29-23-57-14-011_mahindra.com.btl.jpg…

SearchableDropdown.multiple(
items: _dropdownMenuItems,
disabledHint: "Select State*",
selectedItems: selectedState,
displayClearIcon: false,
//hint: Text("Select State *"),
searchHint: "Select State *",
label: Text(
"Select State *",
style: TextStyle(color: Colors.black54),
),
onChanged: (value) {
setState(() {
selectedState = value;
});
if (selectedState.length > 0)
getDealers(selectedState);
},
closeButton: (selectedItems) {
return ("Save");
},
underline: Container(
height: 1.0,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.black38,
width: 1.0))),
),
isExpanded: true,
selectedValueWidgetFn: (item) {
return Container(
transform:
Matrix4.translationValues(-10, 0, 0),
alignment: Alignment.centerLeft,
child: (Text(item.toString())));
},
)

How do I change the style ?

I would like to standardize the style of the field with the other fields in the form.
How should I change the decoration properties?
'''
return TextFormField(
autofocus: false,
onChanged: controller.changeMaterialUnitId,
obscureText: false,
maxLines: 1,
//keyboardType: TextInputType.emailAddress,
cursorColor: Colors.orange,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Unidade',
prefixIcon:
Icon(Icons.face, color: Colors.orange, size: 20),
helperText: ' ',
errorText: controller.validateMaterialUnitId(),
),
)
'''

Adjust selected value padding.

I want to adjust the padding for selectedValue as when we selected the value, the padding between label, selectedValue, underline are way too big.

image

Check Box select

Hello,

I want in some check box selected by default.

I am getting some data from api, i want to match list data and api data, and those are matched, those are selected other are unselected

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.