DropdownButtonFormField<T> constructor Null safety

DropdownButtonFormField<T>(
  1. {Key? key,
  2. required List<DropdownMenuItem<T>>? items,
  3. DropdownButtonBuilder? selectedItemBuilder,
  4. T? value,
  5. Widget? hint,
  6. Widget? disabledHint,
  7. required ValueChanged<T?>? onChanged,
  8. VoidCallback? onTap,
  9. int elevation = 8,
  10. TextStyle? style,
  11. Widget? icon,
  12. Color? iconDisabledColor,
  13. Color? iconEnabledColor,
  14. double iconSize = 24.0,
  15. bool isDense = true,
  16. bool isExpanded = false,
  17. double? itemHeight,
  18. Color? focusColor,
  19. FocusNode? focusNode,
  20. bool autofocus = false,
  21. Color? dropdownColor,
  22. InputDecoration? decoration,
  23. FormFieldSetter<T>? onSaved,
  24. FormFieldValidator<T>? validator,
  25. AutovalidateMode? autovalidateMode,
  26. double? menuMaxHeight,
  27. bool? enableFeedback,
  28. AlignmentGeometry alignment = AlignmentDirectional.centerStart,
  29. BorderRadius? borderRadius}
)

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.

The items, elevation, iconSize, isDense, isExpanded, autofocus, and decoration parameters must not be null.

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,
  // 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(elevation != null),
     assert(iconSize != null),
     assert(isDense != null),
     assert(isExpanded != null),
     assert(itemHeight == null || itemHeight >= kMinInteractiveDimension),
     assert(autofocus != null),
     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();

         // 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) {
             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,
                 inputDecoration: effectiveDecoration.copyWith(errorText: field.errorText),
                 isEmpty: isEmpty,
                 isFocused: Focus.of(context).hasFocus,
               ),
             );
           }),
         );
       },
     );