Multi Select Flutter

Pub Version

Multi Select Flutter is a package for creating multi-select widgets in a variety of ways.


Dialog

BottomSheet

ChoiceChip

Features

  • Supports FormField features like validator.
  • Neutral default design that can be altered to your heart's content.
  • Choose between Dialog, BottomSheet, or ChoiceChip style widgets.
  • Make your multi select searchable for larger lists.

Install

Add this to your pubspec.yaml file:

dependencies:
  multi_select_flutter: ^3.1.2

Usage

MultiSelectDialogField / MultiSelectBottomSheetField

These widgets provide an InkWell button which open the dialog or bottom sheet and are equipped with FormField features. You can customize it to your liking using the provided parameters.

To store the selected values, you can use the onConfirm parameter. You could also use onSelectionChanged for this.

By default these widgets render a MultiSelectChipDisplay below the field. This can be overridden with the chipDisplay parameter or removed completely by using chipDisplay: MultiSelectChipDisplay(items: []).

MultiSelectDialogField(
  items: _animals.map((e) => MultiSelectItem(e, e.name)).toList(),
  listType: MultiSelectListType.CHIP,
  onConfirm: (values) {
    _selectedAnimals = values;
  },
),

MultiSelectDialog / MultiSelectBottomSheet

           

If you prefer to create your own button for opening the dialog or bottom sheet, you may do so and then make a call to a function like this:

MultiSelectDialog can be used in the builder of showDialog().

void _showMultiSelect(BuildContext context) async {
  await showDialog(
    context: context,
    builder: (ctx) {
      return  MultiSelectDialog(
        items: _items,
        initialValue: _selectedAnimals,
        onConfirm: (values) {...},
      );
    },
  );
}

MultiSelectBottomSheet can be used in the builder of showModalBottomSheet().

void _showMultiSelect(BuildContext context) async {
  await showModalBottomSheet(
    isScrollControlled: true, // required for min/max child size
    context: context,
    builder: (ctx) {
      return  MultiSelectBottomSheet(
        items: _items,
        initialValue: _selectedAnimals,
        onConfirm: (values) {...},
        maxChildSize: 0.8,
      );
    },
  );
}

MultiSelectChipDisplay

To display the selected items, this widget can be used alongside your own button or it can be specified as a chipDisplay parameter of widgets like MultiSelectDialogField.

You can also remove items from the source list in the onTap function.

MultiSelectChipDisplay(
  items: _selectedAnimals.map((e) => MultiSelectItem(e, e)).toList(),
  onTap: (value) {
    setState(() {
      _selectedAnimals.remove(value);
    });
  },
),

A MultiSelectChipDisplay that is part of a MultiSelectDialogField still renders outside the BoxDecoration of the MultiSelectDialogField as seen here:

chipDisplay

If you want to encapsulate the MultiSelectChipDisplay, wrap the MultiSelectDialogField in a Container and apply the decoration to that instead:

Container(
  decoration: BoxDecoration(...),
  child: MultiSelectDialogField(
    items: _items,
    chipDisplay: MultiSelectChipDisplay(...),
  ),
),
chipDisplay

MultiSelectChipField

chipField

This widget is similar to MultiSelectChipDisplay, except these chips are the primary interface for selecting items.

MultiSelectChipField<Animal>(
  items: _items,
  icon: Icon(Icons.check),
  onTap: (values) {
    _selectedAnimals = values;
  },
),

Using itemBuilder to create custom items:

MultiSelectChipField<Animal>(
  items: _items,
  key: _multiSelectKey,
  validator: (values) {...}
  itemBuilder: (item, state) {
    // return your custom widget here
    return InkWell(
      onTap: () {
        _selectedAnimals.contains(item.value)
			      ? _selectedAnimals.remove(item.value)
			      : _selectedAnimals.add(item.value);
	      state.didChange(_selectedAnimals);
	      _multiSelectKey.currentState.validate();
	    },
	    child: Text(item.value.name),
    );
  },
),

The itemBuilder param takes a function that will create a widget for each of the provided items.

In order to use validator and other FormField features with custom widgets, you must call state.didChange(_updatedList) any time the list of selected items is updated.

Using scrollControl to auto scroll:

MultiSelectChipField(
  items: _items,
  scrollControl: (controller) {
    _startAnimation(controller);
  },
)

// waits 5 seconds, scrolls to end slow, then back fast
void _startAnimation(ScrollController controller) {
  // when using more than one animation, use async/await
  Future.delayed(const Duration(milliseconds: 5000), () async {
    await controller.animateTo(
      controller.position.maxScrollExtent,
      duration: Duration(milliseconds: 8000), 
      curve: Curves.linear);
      
    await controller.animateTo(
      controller.position.minScrollExtent,
      duration: Duration(milliseconds: 1250),
      curve: Curves.fastLinearToSlowEaseIn);
  });
}

Constructors

MultiSelectDialog

ParameterTypeDefaultDescription
backgroundColorColornullSet the background color of the dialog.
cancelTextTextText("CANCEL")Specifies the cancel button text.
checkColorColornullSet the color of the check in the checkbox.
confirmTextTextText("OK")Specifies the confirm button text.
closeSearchIconIconIcon(Icons.close)The icon button that hides the search field .
coloratorColor Function(V)nullSet the selected color of individual items based on their value. Applies to both chips and checkboxes.
heightdoublenullGive the dialog a fixed height.
initialValueList<V>nullList of selected values. Required to retain values when re-opening the dialog.
itemsList<MultiSelectItem<V>>nullThe source list of options.
itemsTextStyleTextStylenullSpecifies the style of text on chips or list tiles.
listTypeMultiSelectListTypeMultiSelectListType.LISTChange the listType. Can be either  MultiSelectListType.LIST or MultiSelectListType.CHIP
onSelectionChangedFunction(List<V>)nullFires when an item is selected or unselected.
onConfirmFunction(List)nullFires when the confirm button is pressed.
searchableboolfalseToggle search functionality within the dialog.
searchHintStyleTextStylenullStyle the text of the search hint.
searchIconIconIcon(Icons.search)The icon button that shows the search field.
searchHintString"Search"Set the placeholder text of the search field.
searchTextStyleTextStylenullStyle the search text.
selectedColorColornullSet the color of the checkbox or chip items that are selected.
titleTextText("Select")The title that is displayed at the top of the dialog.
unselectedColorColorprimaryColorSet the color of the chip body or checkbox border while not selected.

MultiSelectDialogField

MultiSelectDialogField has all the parameters of MultiSelectDialog plus these extra parameters:

ParameterTypeDefaultDescription
autovalidateModeAutovalidateModeAutovalidateMode.disabledIf enabled, form fields will validate and update their error text immediately after every change. Default is disabled.
barrierColorColornullSet the color of the space outside the dialog.
buttonTextText"Select"Set text that is displayed on the button.
buttonIconIconIcons.arrow_downwardSpecify the button icon.
chipDisplayMultiSelectChipDisplayMultiSelectChipDisplay(...)Override the default MultiSelectChipDisplay that belongs to this field.
decorationBoxDecorationnullStyle the Container that makes up the field.
keyGlobalKey<FormFieldState>nullCan be used to call methods like _multiSelectKey.currentState.validate().
onSavedList<MultiSelectItem>nullA callback that is called whenever we submit the field (usually by calling the save method on a form.
validatorFormFieldValidator<List>nullValidation. See Flutter's documentation.

MultiSelectBottomSheet

ParameterTypeDefaultDescription
cancelTextTextText("CANCEL")Specifies the cancel button text.
checkColorColornullSet the color of the check in the checkbox.
confirmTextTextText("OK")Specifies the confirm button text.
closeSearchIconIconIcon(Icons.close)The icon button that hides the search field .
coloratorColor Function(V)nullSet the selected color of individual items based on their value. Applies to both chips and checkboxes.
initialChildSizedouble0.3The initial height of the BottomSheet.
initialValueList<V>nullList of selected values. Required to retain values when re-opening the BottomSheet.
itemsList<MultiSelectItem<V>>nullThe source list of options.
itemsTextStyleTextStylenullSpecifies the style of text on chips or list tiles.
listTypeMultiSelectListTypeMultiSelectListType.LISTChange the listType. Can be either  MultiSelectListType.LIST or MultiSelectListType.CHIP
maxChildSizedouble0.6Set the maximum height threshold of the BottomSheet.
minChildSizedouble0.3Set the minimum height threshold of the BottomSheet before it closes.
onSelectionChangedFunction(List<V>)nullFires when an item is selected or unselected.
onConfirmFunction(List)nullFires when the confirm button is pressed.
searchableboolfalseToggle search functionality within the BottomSheet.
searchHintString"Search"Set the placeholder text of the search field.
searchHintStyleTextStylenullStyle the text of the search hint.
searchIconIconIcon(Icons.search)The icon button that shows the search field.
searchTextStyleTextStylenullStyle the search text.
selectedColorColornullSet the color of the checkbox or chip items that are selected.
titleTextText("Select")The title that is displayed at the top of the BottomSheet.
unselectedColorColorprimaryColorSet the color of the chip body or checkbox border while not selected.

MultiSelectBottomSheetField

MultiSelectBottomSheetField has all the parameters of MultiSelectBottomSheet plus these extra parameters:

ParameterTypeDefaultUsage
autovalidateModeAutovalidateModeAutovalidateMode.disabledIf enabled, form fields will validate and update their error text immediately after every change. Default is disabled.
backgroundColorColornullSet the background color of the BottomSheet.
barrierColorColornullSet the color of the space outside the BottomSheet.
buttonIconIconIcons.arrow_downwardSpecify the button icon.
buttonTextText"Select"Set text that is displayed on the button.
chipDisplayMultiSelectChipDisplayMultiSelectChipDisplay(...)Override the default MultiSelectChipDisplay that belongs to this field.
decorationBoxDecorationnullStyle the Container that makes up the field.
keyGlobalKey<FormFieldState>nullCan be used to call methods like _multiSelectKey.currentState.validate().
onSavedList<MultiSelectItem>nullA callback that is called whenever we submit the field (usually by calling the save method on a form.
shapeShapeBorderRoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(15.0)))Apply a ShapeBorder to alter the edges of the BottomSheet.
validatorFormFieldValidator<List>nullValidation. See Flutter's documentation.

MultiSelectChipField

ParameterTypeDefaultDescription
autovalidateModeAutovalidateModeAutovalidateMode.disabledIf enabled, form fields will validate and update their error text immediately after every change. Default is disabled.
chipColorColorprimaryColorSet the chip color.
chipShapeShapeBordernullDefine a ShapeBorder for the chips.
closeSearchIconIconIcon(Icons.close)The icon button that hides the search field .
coloratorColor Function(V)nullSet the selected chip color of individual items based on their value.
decorationBoxDecorationnullStyle the surrounding Container.
headerColorColorprimaryColorSet the header color.
heightdoublenullSet the height of the selectable area.
iconIconnullThe icon to display prior to the chip label.
initialValueList<V>nullList of selected values before any interaction.
itemBuilderFunction(MultiSelectItem<V>, FormFieldState<List<V>>)nullBuild a custom widget that gets created dynamically for each item.
itemsList<MultiSelectItem<V>>nullThe source list of options.
keyGlobalKey<FormFieldState>nullCan be used to call methods like _multiSelectKey.currentState.validate().
onSavedList<MultiSelectItem>nullA callback that is called whenever the field is submitted (usually by calling the save method on a form.
onTapFunction(V)nullFires when a chip is tapped.
scrollbooltrueEnables horizontal scrolling.
scrollBarHorizontalScrollBarnullDefine a scroll bar.
scrollControlFunction(ScrollController)nullMake use of the ScrollController to automatically scroll through the list.
searchableboolfalseToggle search functionality.
searchHintString"Search"Set the placeholder text of the search field.
searchHintStyleTextStylenullStyle the text of the search hint.
searchIconIconIcon(Icons.search)The icon button that shows the search field.
searchTextStyleTextStylenullStyle the search text.
selectedChipColorColornullSet the color of the chip items that are selected.
selectedTextStyleTextStylenullSet the TextStyle on selected chips.
showHeaderbooltrueDetermines whether to show the header.
textStyleTextStylenullStyle the text on the chips.
titleTextText("Select")The title that is displayed in the header.
validatorFormFieldValidator<List>nullValidation. See Flutter's documentation.

MultiSelectChipDisplay

ParameterTypeDefaultDescription
alignmentAlignmentAlignment.centerLeftChange the alignment of the chips.
chipColorColorprimaryColorSet the chip color.
coloratorColor Function(V)nullSet the chip color of individual items based on their value.
decorationBoxDecorationnullStyle the Container that makes up the chip display.
heightdoublenullSet a fixed height.
iconIconnullThe icon to display prior to the chip label.
itemsList<MultiSelectItem>nullThe source list of selected items.
onTapFunction(V)nullFires when a chip is tapped.
scrollboolfalseEnables horizontal scroll instead of wrap.
scrollBarHorizontalScrollBarnullEnable the scroll bar.
shapeShapeBordernullDefine a ShapeBorder for the chips.
textStyleTextStylenullStyle the text on the chips.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Libraries

horizontal_scrollbar
mult_select_dialog
multi_select_actions
multi_select_bottom_sheet
multi_select_bottom_sheet_field
multi_select_chip_display
multi_select_chip_field
multi_select_dialog_field
multi_select_flutter
multi_select_item
multi_select_list_type