DropdownButtonFormField<T> constructor
- Key? key,
- required List<
DropdownMenuItem< ? items,T> > - DropdownButtonBuilder? selectedItemBuilder,
- T? value,
- Widget? hint,
- Widget? disabledHint,
- required ValueChanged<
T?> ? onChanged, - VoidCallback? onTap,
- int elevation = 8,
- TextStyle? style,
- Widget? icon,
- Color? iconDisabledColor,
- Color? iconEnabledColor,
- double iconSize = 24.0,
- bool isDense = true,
- bool isExpanded = false,
- double? itemHeight,
- Color? focusColor,
- FocusNode? focusNode,
- bool autofocus = false,
- Color? dropdownColor,
- InputDecoration? decoration,
- FormFieldSetter<
T> ? onSaved, - FormFieldValidator<
T> ? validator, - AutovalidateMode? autovalidateMode,
- bool? enableFeedback,
- AlignmentGeometry alignment = AlignmentDirectional.centerStart,
- BorderRadius? borderRadius,
- EdgeInsetsGeometry? padding,
Creates a DropdownButton widget that is a FormField, wrapped in an InputDecorator.
For a description of the onSaved
, validator
, or autovalidateMode
parameters, see FormField. For the rest (other than decoration
), see
DropdownButton.
Implementation
DropdownButtonFormField({
super.key,
required List<DropdownMenuItem<T>>? items,
DropdownButtonBuilder? selectedItemBuilder,
T? value,
Widget? hint,
Widget? disabledHint,
required this.onChanged,
VoidCallback? onTap,
int elevation = 8,
TextStyle? style,
Widget? icon,
Color? iconDisabledColor,
Color? iconEnabledColor,
double iconSize = 24.0,
bool isDense = true,
bool isExpanded = false,
double? itemHeight,
Color? focusColor,
FocusNode? focusNode,
bool autofocus = false,
Color? dropdownColor,
InputDecoration? decoration,
super.onSaved,
super.validator,
AutovalidateMode? autovalidateMode,
double? menuMaxHeight,
bool? enableFeedback,
AlignmentGeometry alignment = AlignmentDirectional.centerStart,
BorderRadius? borderRadius,
EdgeInsetsGeometry? padding,
// When adding new arguments, consider adding similar arguments to
// DropdownButton.
}) : assert(items == null || items.isEmpty || value == null ||
items.where((DropdownMenuItem<T> item) {
return item.value == value;
}).length == 1,
"There should be exactly one item with [DropdownButton]'s value: "
'$value. \n'
'Either zero or 2 or more [DropdownMenuItem]s were detected '
'with the same value',
),
assert(itemHeight == null || itemHeight >= kMinInteractiveDimension),
decoration = decoration ?? InputDecoration(focusColor: focusColor),
super(
initialValue: value,
autovalidateMode: autovalidateMode ?? AutovalidateMode.disabled,
builder: (FormFieldState<T> field) {
final _DropdownButtonFormFieldState<T> state = field as _DropdownButtonFormFieldState<T>;
final InputDecoration decorationArg = decoration ?? InputDecoration(focusColor: focusColor);
final InputDecoration effectiveDecoration = decorationArg.applyDefaults(
Theme.of(field.context).inputDecorationTheme,
);
final bool showSelectedItem = items != null && items.where((DropdownMenuItem<T> item) => item.value == state.value).isNotEmpty;
bool isHintOrDisabledHintAvailable() {
final bool isDropdownDisabled = onChanged == null || (items == null || items.isEmpty);
if (isDropdownDisabled) {
return hint != null || disabledHint != null;
} else {
return hint != null;
}
}
final bool isEmpty = !showSelectedItem && !isHintOrDisabledHintAvailable();
final bool hasError = effectiveDecoration.errorText != null;
// An unfocusable Focus widget so that this widget can detect if its
// descendants have focus or not.
return Focus(
canRequestFocus: false,
skipTraversal: true,
child: Builder(builder: (BuildContext context) {
final bool isFocused = Focus.of(context).hasFocus;
InputBorder? resolveInputBorder() {
if (hasError) {
if (isFocused) {
return effectiveDecoration.focusedErrorBorder;
}
return effectiveDecoration.errorBorder;
}
if (isFocused) {
return effectiveDecoration.focusedBorder;
}
if (effectiveDecoration.enabled) {
return effectiveDecoration.enabledBorder;
}
return effectiveDecoration.border;
}
BorderRadius? effectiveBorderRadius() {
final InputBorder? inputBorder = resolveInputBorder();
if (inputBorder is OutlineInputBorder) {
return inputBorder.borderRadius;
}
if (inputBorder is UnderlineInputBorder) {
return inputBorder.borderRadius;
}
return null;
}
return DropdownButtonHideUnderline(
child: DropdownButton<T>._formField(
items: items,
selectedItemBuilder: selectedItemBuilder,
value: state.value,
hint: hint,
disabledHint: disabledHint,
onChanged: onChanged == null ? null : state.didChange,
onTap: onTap,
elevation: elevation,
style: style,
icon: icon,
iconDisabledColor: iconDisabledColor,
iconEnabledColor: iconEnabledColor,
iconSize: iconSize,
isDense: isDense,
isExpanded: isExpanded,
itemHeight: itemHeight,
focusColor: focusColor,
focusNode: focusNode,
autofocus: autofocus,
dropdownColor: dropdownColor,
menuMaxHeight: menuMaxHeight,
enableFeedback: enableFeedback,
alignment: alignment,
borderRadius: borderRadius ?? effectiveBorderRadius(),
inputDecoration: effectiveDecoration.copyWith(errorText: field.errorText),
isEmpty: isEmpty,
isFocused: isFocused,
padding: padding,
),
);
}),
);
},
);