dropdown_search 7.0.0-pre2 copy "dropdown_search: ^7.0.0-pre2" to clipboard
dropdown_search: ^7.0.0-pre2 copied to clipboard

Simple, reactive and highly customizable Flutter Dropdown with a lot of features (search, popups platform, async/sync,...) with multi mode like menu, dialog, bottomSheet and etc.

Flutter DropdownSearch

Simple and highly customizable Flutter Dropdown with a lot of features (search, adaptive, async/sync values, ...) with multi mode like menu, modal, dialog, bottomSheet and etc.

Build

Key FeaturesExamplesLicense

Dropdown search

Key Features #

  • Reactive widget
  • Infinite list (lazy loading)
  • Sync and/or Async items (online, offline, DB, ...)
  • Searchable dropdown
  • Support multi level items
  • Five dropdown modes: Menu / BottomSheet / ModalBottomSheet / Dialog / autocomplete
  • Single & multi selection
  • Adaptive platform UI : Material, Adaptive, Cupertino
  • Easy customizable UI - No Boilerplate

Dropdown search

Dropdown search
Dropdown search
Dropdown search Dropdown search

Dropdown search

pubspec.yaml #

dropdown_search: <lastest version>

Import #

import 'package:dropdown_search/dropdown_search.dart';

Adaptive Platform UI #

  • To use Material ui (by default) use DropdownSearch<T>(...) or DropdownSearch<T>.multiSelection(...)

  • for the cupertino mode use CupertinoDropdownSearch<T>(...) or CupertinoDropdownSearch<T>.multiSelection(...)

  • To let the package pick the suitable platform UI based on the used platform, use AdaptiveDropdownSearch<T>(...) or AdaptiveDropdownSearch<T>.multiSelection(...)

  • Bonus Tip: with adaptive platform ui you can use different PopupMode depending on platform type:

AdaptiveDropdownSearch<T>(
    popupProps: AdaptivePopupProps(
        cupertinoProps: CupertinoPopupProps.bottomSheet(),
        materialProps: PopupProps.dialog()
    ),
)

Infinite Scroll #

To enable infinite scroll all you have to do is to declare infiniteScrollProps and of course don't forget to pass loadProps to your API like this:

DropdownSearch<T>(
    items: (filter, loadProps) => _getDataFromAPI(filter, loadProps!.skip, loadProps!.take),
    popupProps: PopupProps.dialog(
        infiniteScrollProps: InfiniteScrollProps(
            loadProps: LoadProps(skip: 0, take: 10),
        ),
    ),
)

Simple implementation #

See here
DropdownSearch<String>(
  items: (f, cs) => ["Item 1", 'Item 2', 'Item 3', 'Item 4'],
  popupProps: PopupProps.menu(
    disabledItemFn: (item) => item == 'Item 3',
    fit: FlexFit.loose
  ),
),
Dropdown search
DropdownSearch<String>.multiSelection(
  mode: Mode.CUSTOM,
  items: (f, cs) => ["Monday", 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
  dropdownBuilder: (ctx, selectedItem) => Icon(Icons.calendar_month_outlined, size: 54),
),
Dropdown search
DropdownSearch<(String, Color)>(
  clickProps: ClickProps(borderRadius: BorderRadius.circular(20)),
  mode: Mode.CUSTOM,
  items: (f, cs) => [
    ("Red", Colors.red),
    ("Black", Colors.black),
    ("Yellow", Colors.yellow),
    ('Blue', Colors.blue),
  ],
  compareFn: (item1, item2) => item1.$1 == item2.$1,
  popupProps: PopupProps.menu(
  menuProps: MenuProps(align: MenuAlign.bottomCenter),
    fit: FlexFit.loose,
    itemBuilder: (context, item, isDisabled, isSelected) => Padding(
      padding: const EdgeInsets.all(8.0),
      child: Text(item.$1, style: TextStyle(color: item.$2, fontSize: 16)),
    ),
  ),
  dropdownBuilder: (ctx, selectedItem) => Icon(Icons.face, color: selectedItem?.$2, size: 54),
),
Dropdown search
DropdownSearch<(IconData, String)>(
  selectedItem: (Icons.person, 'Your Profile'),
  compareFn: (item1, item2) => item1.$1 == item2.$2,
  items: (f, cs) => [
    (Icons.person, 'Your Profile'),
    (Icons.settings, 'Setting'),
    (Icons.lock_open_rounded, 'Change Password'),
    (Icons.power_settings_new_rounded, 'Logout'),
  ],
  decoratorProps: DropDownDecoratorProps(
    decoration: InputDecoration(
      contentPadding: EdgeInsets.symmetric(vertical: 6),
      filled: true,
      fillColor: Color(0xFF1eb98f),
      border: OutlineInputBorder(
        borderSide: BorderSide(color: Colors.transparent),
        borderRadius: BorderRadius.circular(8),
      ),
      focusedBorder: OutlineInputBorder(
        borderSide: BorderSide(color: Colors.transparent),
        borderRadius: BorderRadius.circular(8),
      ),
      enabledBorder: OutlineInputBorder(
        borderSide: BorderSide(color: Colors.transparent),
        borderRadius: BorderRadius.circular(8),
      ),
    ),
  ),
  dropdownBuilder: (context, selectedItem) {
    return ListTile(
      leading: Icon(selectedItem!.$1, color: Colors.white),
      title: Text(
        selectedItem.$2,
        style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold),
      ),
    );
  },
  popupProps: PopupProps.menu(
    itemBuilder: (context, item, isDisabled, isSelected) {
      return ListTile(
        contentPadding: EdgeInsets.symmetric(vertical: 8, horizontal: 12),
        leading: Icon(item.$1, color: Colors.white),
        title: Text(
          item.$2,
          style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold),
        ),
      );
    },
    fit: FlexFit.loose,
    menuProps: MenuProps(
      backgroundColor: Colors.transparent,
      elevation: 0,
      margin: EdgeInsets.only(top: 16),
    ),
    containerBuilder: (ctx, popupWidget) {
      return Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [
          Padding(
            padding: const EdgeInsets.only(right: 12),
            child: Image.asset(
              'assets/images/arrow-up.png',
              color: Color(0xFF1eb98f),
              height: 14,
            ),
          ),
          Flexible(
            child: Container(
              decoration: BoxDecoration(
                color: Color(0xFF1eb98f),
                shape: BoxShape.rectangle,
                borderRadius: BorderRadius.circular(8),
              ),
              child: popupWidget,
            ),
          ),
        ],
      );
    },
  ),
),
Dropdown search
DropdownSearch<String>(
  items: (filter, infiniteScrollProps) => ['Item 1', 'Item 2', 'Item 3'],
  suffixProps: DropdownSuffixProps(
    dropdownButtonProps: DropdownButtonProps(
      iconClosed: Icon(Icons.keyboard_arrow_down),
      iconOpened: Icon(Icons.keyboard_arrow_up),
    ),
  ),
  decoratorProps: DropDownDecoratorProps(
    textAlign: TextAlign.center,
    decoration: InputDecoration(
      contentPadding: EdgeInsets.symmetric(vertical: 20),
      filled: true,
      fillColor: Colors.white,
      border: OutlineInputBorder(
        borderSide: BorderSide(color: Colors.transparent),
        borderRadius: BorderRadius.circular(12),
      ),
      focusedBorder: OutlineInputBorder(
        borderSide: BorderSide(color: Colors.transparent),
        borderRadius: BorderRadius.circular(12),
      ),
      enabledBorder: OutlineInputBorder(
        borderSide: BorderSide(color: Colors.transparent),
        borderRadius: BorderRadius.circular(12),
      ),
      hintText: 'Please select...',
      hintStyle: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.grey),
    ),
  ),
  popupProps: PopupProps.menu(
    itemBuilder: (context, item, isDisabled, isSelected) {
      return Padding(
        padding: const EdgeInsets.symmetric(vertical: 12.0),
        child: Text(
          item,
          style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
          textAlign: TextAlign.center,
        ),
      );
    },
    constraints: BoxConstraints(maxHeight: 160),
    menuProps: MenuProps(
      margin: EdgeInsets.only(top: 12),
      shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12))),
    ),
  ),
),
Dropdown search
DropdownSearch<UserModel>.multiSelection(
  items: (filter, s) => getData(filter),
  compareFn: (i, s) => i.isEqual(s),
  popupProps: PopupPropsMultiSelection.bottomSheet(
    bottomSheetProps: BottomSheetProps(backgroundColor: Colors.blueGrey[50]),
    showSearchBox: true,
    itemBuilder: userModelPopupItem,
    suggestedItemProps: SuggestedItemProps(
      showSuggestedItems: true,
      suggestedItems: (us) {
        return us.where((e) => e.name.contains("Mrs")).toList();
      },
    ),
  ),
),
Dropdown search
DropdownSearch<int>(
  items: (f, cs) => List.generate(30, (i) => i + 1),
  decoratorProps: DropDownDecoratorProps(
    decoration: InputDecoration(labelText: "Dialog with title", hintText: "Select an Int"),
  ),
  popupProps: PopupProps.dialog(
    title: Container(
      decoration: BoxDecoration(color: Colors.deepPurple),
      alignment: Alignment.center,
      padding: EdgeInsets.symmetric(vertical: 16),
      child: Text(
        'Numbers 1..30',
        style: TextStyle(fontSize: 21, fontWeight: FontWeight.bold, color: Colors.white70),
      ),
    ),
    dialogProps: DialogProps(
      clipBehavior: Clip.antiAlias,
      shape: OutlineInputBorder(
        borderSide: BorderSide(width: 0),
        borderRadius: BorderRadius.circular(25),
      ),
    ),
  ),
),
Dropdown search

Layout customization #

You can customize the layout of the DropdownSearch and its items. click here for more examples.

Full documentation here

DropdownSearch Anatomy Dropdown search

Support #

If this plugin was useful to you, helped you to deliver your app, saved you a lot of time, or you just want to support the project, I would be very grateful if you buy me a cup of coffee.

Buy Me A Coffee

License #

MIT

1.81k
likes
160
points
143k
downloads

Publisher

verified publishersalimdev.ovh

Weekly Downloads

Simple, reactive and highly customizable Flutter Dropdown with a lot of features (search, popups platform, async/sync,...) with multi mode like menu, dialog, bottomSheet and etc.

Homepage
Repository (GitHub)
View/report issues

Topics

#dropdown #autocomplete #form #material #popups

Documentation

API reference

License

MIT (license)

Dependencies

cupertino_icons, flutter

More

Packages that depend on dropdown_search