最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

flutter - How to define Dropdown Menu SearchCallback - Stack Overflow

matteradmin7PV0评论

I want to implement a text search in Dropdown Flutter/Dart.

I want to use Flutter/Dart DropdownMenu class.

I don't want to use DropDownButton b/c it does not have a search.

The DropdownMenu Search class has SearchCallback.

The DropdownMenu class has 3 key things: List, Controller, and SearchCallback.

I want to use Controller to search the Controller's input text.

The SearchCallback has two things: entries and query.

I am not certain how to define the SearchCallback correctly.

Could you please provide example of SearchCallback.

Thank You

I want to implement a text search in Dropdown Flutter/Dart.

I want to use Flutter/Dart DropdownMenu class.

I don't want to use DropDownButton b/c it does not have a search.

The DropdownMenu Search class has SearchCallback.

The DropdownMenu class has 3 key things: List, Controller, and SearchCallback.

I want to use Controller to search the Controller's input text.

The SearchCallback has two things: entries and query.

I am not certain how to define the SearchCallback correctly.

Could you please provide example of SearchCallback.

Thank You

Share Improve this question edited Nov 19, 2024 at 11:07 sillycone 5263 silver badges13 bronze badges asked Nov 16, 2024 at 23:45 DktPhl2018DktPhl2018 4831 gold badge5 silver badges12 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

Imagine a function that takes a list of DropdownMenuEntrys ("entries") and a String ("query"), and returns an int for the index of a DropdownMenuEntry in the list that matches the string. This is the function you are passing as the SearchCallback parameter. If you leave it blank, it will default to a function that returns the index of first entry that contains the query anywhere in it. You can write your own function to customize the search. For example, here is a function you could write that returns the index of the first entry that matches the query exactly.

DropdownMenu<Text>(
  searchCallback: (List<DropdownMenuEntry<Text>> entries, String query) {
    if (query.isEmpty) {
      return null;
    }
    final int index = entries.indexWhere((DropdownMenuEntry<Text> entry) => entry.label == query);

    return index != -1 ? index : null;
  },
  dropdownMenuEntries: const <DropdownMenuEntry<Text>>[],
)

I used flutter auto complete widget like below and also I implementing this using TextEditingController also in generic clean way let me know if you have any questions

class DropdownSearch<T extends DropAble> extends StatelessWidget {
  final TextEditingController textController;
  final List<T> items;
  final void Function(T) onSuggestionSelected;
  final bool required;
  final String placeHolder;
  final String label;
  final String? Function(T?) validator;

  const DropdownSearch({
    super.key,
    required this.textController,
    required this.items,
    required this.onSuggestionSelected,
    this.required = false,
    this.label = "",
    this.placeHolder = "",
    required this.validator,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 14),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            "${required ? "* " : ""}$label",
            style: Theme.of(context).textTheme.labelMedium,
          ),
          const SizedBox(
            height: 14,
          ),
          RawAutocomplete<String>(
            optionsBuilder: (TextEditingValue textEditingValue) {
            return  items.map((e)=>e.name ?? "").toList()
                  .where((item) =>
                  (item).toLowerCase().contains(textEditingValue.text.toLowerCase()))
                  .toList();
            },
            onSelected: (String selection) {
              textController.text = selection;
              T? item = items.firstWhereOrNull((element) => element.name == selection);
              if (item != null) {
                onSuggestionSelected(item);
              }
            },
            fieldViewBuilder: (
                BuildContext context,
                TextEditingController textEditingController,
                FocusNode focusNode,
                VoidCallback onFieldSubmitted,
                ) {
              return TextFormField(
                controller: textEditingController,
                decoration:  InputDecoration(
                  hintText: placeHolder,
                ),
                focusNode: focusNode,
                onFieldSubmitted: (String value) {
                  T? item = items.firstWhereOrNull((element) => element.name == value);
                  onFieldSubmitted();
                  if (item != null) {
                    onSuggestionSelected(item);
                  }
                },
               // validator: vali,
              );
            },
            optionsViewBuilder: (
                BuildContext context,
                AutocompleteOnSelected<String> onSelected,
                Iterable<String> options,
                ) {
              return Align(
                alignment: Get.locale?.languageCode == "ar" ? Alignment.topRight : Alignment.topLeft,
                child: Material(
                  elevation: 4.0,
                  child: SizedBox(
                    width: Get.width-70,
                    child: ListView.builder(
                      shrinkWrap: true,
                      padding: const EdgeInsets.all(8.0),
                      itemCount: options.length,
                      itemBuilder: (BuildContext context, int index) {
                        final  option = options.elementAt(index);
                        return GestureDetector(
                          onTap: () {
                            textController.text = option;
                            onSelected(option);
                            T? item = items.firstWhereOrNull((element) => element.name == option);
                            if(item != null){
                              onSuggestionSelected(item);
                            }
                          },
                          child: ListTile(
                            title: Text(option),
                          ),
                        );
                      },
                    ),
                  ),
                ),
              );
            },
          ),
          const SizedBox(
            height: 14,
          ),
        ],
      ),
    );
  }
}
Post a comment

comment list (0)

  1. No comments so far