CustomDropdown<T> class
A highly customizable, production-ready generic dropdown widget wrapping Flutter's DropdownMenu.
Features
- Full Layout Customization: Use
itemBuilderto create any item UI - Type-Safe Generic Support: Works with any model class via generic type parameter
- Icon Support: Add
prefixIcon,suffixIcon,leadingIcon, ortrailingIcon - Enable/Disable: Control interaction with
enabledproperty - Complete Styling: MenuStyle, border radius, colors, elevation
- Validation: Display validation messages with
validationMessage - Search & Filter: Built-in search and filter capabilities
Basic Usage
Simple String Dropdown
CustomDropdown<String>(
items: ['Apple', 'Banana', 'Orange'],
itemBuilder: (context, item) => Text(item),
onSelected: (value) => print('Selected: $value'),
label: Text('Choose Fruit'),
)
Model Class with Icons
class Country {
final String name;
final String flag;
Country(this.name, this.flag);
}
CustomDropdown<Country>(
items: [
Country('USA', '🇺🇸'),
Country('India', '🇮🇳'),
Country('Japan', '🇯🇵'),
],
itemBuilder: (context, country) => Row(
children: [
Text(country.flag, style: TextStyle(fontSize: 20)),
SizedBox(width: 10),
Text(country.name),
],
),
prefixIcon: Icon(Icons.flag),
onSelected: (value) => setState(() => selected = value),
)
With Validation
CustomDropdown<String>(
items: ['Option 1', 'Option 2'],
itemBuilder: (context, item) => Text(item),
onSelected: (value) => setState(() => selected = value),
validationMessage: selected == null ? 'Please select an option' : null,
)
Custom Styling
CustomDropdown<String>(
items: ['Light', 'Dark', 'Auto'],
itemBuilder: (context, item) => Text(item),
borderRadius: 12,
menuBackgroundColor: Colors.blue.shade50,
menuElevation: 8,
onSelected: (value) => print(value),
)
Advanced Customization
For complete control, use menuStyle for the dropdown panel and
dropdownMenuEntries with custom ButtonStyle for individual items.
Reference: https://api.flutter.dev/flutter/material/DropdownMenu-class.html
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- CustomDropdown
Constructors
-
CustomDropdown({Key? key, required Widget itemBuilder(BuildContext, T item), List<
T> ? items, List<DropdownMenuEntry< ? dropdownMenuEntries, T? initialSelection, ValueChanged<T> >T?> ? onSelected, bool enabled = true, bool enableFilter = false, bool enableSearch = true, TextEditingController? controller, TextStyle? textStyle, Object? inputDecorationTheme, Widget? leadingIcon, Widget? trailingIcon, bool showTrailingIcon = true, FocusNode? trailingIconFocusNode, Widget? selectedTrailingIcon, Widget? label, String? hintText, String? helperText, String? errorText, TextInputType? keyboardType, TextAlign textAlign = TextAlign.start, EdgeInsetsGeometry? expandedInsets, FilterCallback<T> ? filterCallback, SearchCallback<T> ? searchCallback, Offset? alignmentOffset, List<TextInputFormatter> ? inputFormatters, DropdownMenuCloseBehavior closeBehavior = DropdownMenuCloseBehavior.all, int? maxLines = 1, TextInputAction? textInputAction, double? cursorHeight, String? restorationId, bool? requestFocusOnTap, Widget selectedBuilder(BuildContext, T?)?, String? validationMessage, TextStyle? validationTextStyle, double? width, Widget? prefixIcon, Widget? suffixIcon, double? borderRadius, }) -
const
Properties
- alignmentOffset → Offset?
-
final
- borderRadius → double?
-
final
- closeBehavior → DropdownMenuCloseBehavior
-
final
- controller → TextEditingController?
-
final
- cursorHeight → double?
-
final
-
dropdownMenuEntries
→ List<
DropdownMenuEntry< ?T> > -
final
- enabled → bool
-
final
- enableFilter → bool
-
final
- enableSearch → bool
-
final
- errorText → String?
-
final
- expandedInsets → EdgeInsetsGeometry?
-
final
-
filterCallback
→ FilterCallback<
T> ? -
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- helperText → String?
-
final
- hintText → String?
-
final
- initialSelection → T?
-
final
- inputDecorationTheme → Object?
-
final
-
inputFormatters
→ List<
TextInputFormatter> ? -
final
- itemBuilder → Widget Function(BuildContext, T item)
-
final
-
items
→ List<
T> ? -
final
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
- keyboardType → TextInputType?
-
final
- label → Widget?
-
final
- leadingIcon → Widget?
-
final
- maxLines → int?
-
final
-
final
-
final
-
final
-
final
-
final
-
onSelected
→ ValueChanged<
T?> ? -
final
- prefixIcon → Widget?
-
final
- requestFocusOnTap → bool?
-
final
- restorationId → String?
-
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
-
searchCallback
→ SearchCallback<
T> ? -
final
- selectedBuilder → Widget Function(BuildContext, T?)?
-
final
- selectedTrailingIcon → Widget?
-
final
- showTrailingIcon → bool
-
final
- suffixIcon → Widget?
-
final
- textAlign → TextAlign
-
final
- textInputAction → TextInputAction?
-
final
- textStyle → TextStyle?
-
final
- trailingIcon → Widget?
-
final
- trailingIconFocusNode → FocusNode?
-
final
- validationMessage → String?
-
final
- validationTextStyle → TextStyle?
-
final
- width → double?
-
final
Methods
-
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree.
inherited
-
createState(
) → State< CustomDropdown< T> > -
Creates the mutable state for this widget at a given location in the tree.
override
-
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of DiagnosticsNode objects describing this node's
children.
inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toDiagnosticsNode(
{String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep.
inherited
-
toString(
{DiagnosticLevel minLevel = DiagnosticLevel.info}) → String -
A string representation of this object.
inherited
-
toStringDeep(
{String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String -
Returns a string representation of this node and its descendants.
inherited
-
toStringShallow(
{String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String -
Returns a one-line detailed description of the object.
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited