Commit 45d57e78 authored by Sarbagya Dhaubanjar's avatar Sarbagya Dhaubanjar Committed by Shi-Hao Hong

Added properties in DropdownButtonFormField to match DropdownButton (#36998)

* Added properties in DropdownFormField to match DropdownButton

* Minor style guide related changes
parent 77f71ef4
...@@ -39,4 +39,5 @@ Marco Scannadinari <m@scannadinari.co.uk> ...@@ -39,4 +39,5 @@ Marco Scannadinari <m@scannadinari.co.uk>
Frederik Schweiger <mail@flschweiger.net> Frederik Schweiger <mail@flschweiger.net>
Martin Staadecker <machstg@gmail.com> Martin Staadecker <machstg@gmail.com>
Igor Katsuba <katsuba.igor@gmail.com> Igor Katsuba <katsuba.igor@gmail.com>
Diego Velásquez <diego.velasquez.lopez@gmail.com> Diego Velásquez <diego.velasquez.lopez@gmail.com>
\ No newline at end of file Sarbagya Dhaubanjar <mail@sarbagyastha.com.np>
\ No newline at end of file
...@@ -184,24 +184,24 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> { ...@@ -184,24 +184,24 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> {
explicitChildNodes: true, explicitChildNodes: true,
label: localizations.popupMenuLabel, label: localizations.popupMenuLabel,
child: Material( child: Material(
type: MaterialType.transparency, type: MaterialType.transparency,
textStyle: route.style, textStyle: route.style,
child: ScrollConfiguration( child: ScrollConfiguration(
behavior: const _DropdownScrollBehavior(), behavior: const _DropdownScrollBehavior(),
child: Scrollbar( child: Scrollbar(
child: ListView( child: ListView(
controller: widget.route.scrollController, controller: widget.route.scrollController,
padding: kMaterialListPadding, padding: kMaterialListPadding,
itemExtent: _kMenuItemHeight, itemExtent: _kMenuItemHeight,
shrinkWrap: true, shrinkWrap: true,
children: children, children: children,
),
), ),
), ),
), ),
), ),
), ),
); ),
);
} }
} }
...@@ -253,7 +253,7 @@ class _DropdownMenuRouteLayout<T> extends SingleChildLayoutDelegate { ...@@ -253,7 +253,7 @@ class _DropdownMenuRouteLayout<T> extends SingleChildLayoutDelegate {
double left; double left;
switch (textDirection) { switch (textDirection) {
case TextDirection.rtl: case TextDirection.rtl:
left = buttonRect.right.clamp(0.0, size.width) - childSize.width; left = buttonRect.right.clamp(0.0, size.width) - childSize.width;
break; break;
case TextDirection.ltr: case TextDirection.ltr:
left = buttonRect.left.clamp(0.0, size.width - childSize.width); left = buttonRect.left.clamp(0.0, size.width - childSize.width);
...@@ -637,7 +637,7 @@ class DropdownButton<T> extends StatefulWidget { ...@@ -637,7 +637,7 @@ class DropdownButton<T> extends StatefulWidget {
/// if the first item were selected. /// if the first item were selected.
final T value; final T value;
/// Displayed if [value] is null. /// A placeholder widget that is displayed if no item is selected, i.e. if [value] is null.
final Widget hint; final Widget hint;
/// A message to show when the dropdown is disabled. /// A message to show when the dropdown is disabled.
...@@ -645,12 +645,14 @@ class DropdownButton<T> extends StatefulWidget { ...@@ -645,12 +645,14 @@ class DropdownButton<T> extends StatefulWidget {
/// Displayed if [items] or [onChanged] is null. /// Displayed if [items] or [onChanged] is null.
final Widget disabledHint; final Widget disabledHint;
/// {@template flutter.material.dropdownButton.onChanged}
/// Called when the user selects an item. /// Called when the user selects an item.
/// ///
/// If the [onChanged] callback is null or the list of [items] is null /// If the [onChanged] callback is null or the list of [items] is null
/// then the dropdown button will be disabled, i.e. its arrow will be /// then the dropdown button will be disabled, i.e. its arrow will be
/// displayed in grey and it will not respond to input. A disabled button /// displayed in grey and it will not respond to input. A disabled button
/// will display the [disabledHint] widget if it is non-null. /// will display the [disabledHint] widget if it is non-null.
/// {@endtemplate}
final ValueChanged<T> onChanged; final ValueChanged<T> onChanged;
/// The z-coordinate at which to place the menu when open. /// The z-coordinate at which to place the menu when open.
...@@ -777,7 +779,7 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi ...@@ -777,7 +779,7 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
final Rect itemRect = itemBox.localToGlobal(Offset.zero) & itemBox.size; final Rect itemRect = itemBox.localToGlobal(Offset.zero) & itemBox.size;
final TextDirection textDirection = Directionality.of(context); final TextDirection textDirection = Directionality.of(context);
final EdgeInsetsGeometry menuMargin = ButtonTheme.of(context).alignedDropdown final EdgeInsetsGeometry menuMargin = ButtonTheme.of(context).alignedDropdown
?_kAlignedMenuMargin ? _kAlignedMenuMargin
: _kUnalignedMenuMargin; : _kUnalignedMenuMargin;
assert(_dropdownRoute == null); assert(_dropdownRoute == null);
...@@ -813,22 +815,20 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi ...@@ -813,22 +815,20 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
Color get _iconColor { Color get _iconColor {
// These colors are not defined in the Material Design spec. // These colors are not defined in the Material Design spec.
if (_enabled) { if (_enabled) {
if (widget.iconEnabledColor != null) { if (widget.iconEnabledColor != null)
return widget.iconEnabledColor; return widget.iconEnabledColor;
}
switch(Theme.of(context).brightness) { switch (Theme.of(context).brightness) {
case Brightness.light: case Brightness.light:
return Colors.grey.shade700; return Colors.grey.shade700;
case Brightness.dark: case Brightness.dark:
return Colors.white70; return Colors.white70;
} }
} else { } else {
if (widget.iconDisabledColor != null) { if (widget.iconDisabledColor != null)
return widget.iconDisabledColor; return widget.iconDisabledColor;
}
switch(Theme.of(context).brightness) { switch (Theme.of(context).brightness) {
case Brightness.light: case Brightness.light:
return Colors.grey.shade400; return Colors.grey.shade400;
case Brightness.dark: case Brightness.dark:
...@@ -852,8 +852,9 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi ...@@ -852,8 +852,9 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
final List<Widget> items = _enabled ? List<Widget>.from(widget.items) : <Widget>[]; final List<Widget> items = _enabled ? List<Widget>.from(widget.items) : <Widget>[];
int hintIndex; int hintIndex;
if (widget.hint != null || (!_enabled && widget.disabledHint != null)) { if (widget.hint != null || (!_enabled && widget.disabledHint != null)) {
final Widget emplacedHint = final Widget emplacedHint = _enabled
_enabled ? widget.hint : DropdownMenuItem<Widget>(child: widget.disabledHint ?? widget.hint); ? widget.hint
: DropdownMenuItem<Widget>(child: widget.disabledHint ?? widget.hint);
hintIndex = items.length; hintIndex = items.length;
items.add(DefaultTextStyle( items.add(DefaultTextStyle(
style: _textStyle.copyWith(color: Theme.of(context).hintColor), style: _textStyle.copyWith(color: Theme.of(context).hintColor),
...@@ -893,7 +894,9 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi ...@@ -893,7 +894,9 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
widget.isExpanded ? Expanded(child: innerItemsWidget) : innerItemsWidget, widget.isExpanded
? Expanded(child: innerItemsWidget)
: innerItemsWidget,
IconTheme( IconTheme(
data: IconThemeData( data: IconThemeData(
color: _iconColor, color: _iconColor,
...@@ -918,7 +921,12 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi ...@@ -918,7 +921,12 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> with WidgetsBindi
child: widget.underline ?? Container( child: widget.underline ?? Container(
height: 1.0, height: 1.0,
decoration: const BoxDecoration( decoration: const BoxDecoration(
border: Border(bottom: BorderSide(color: Color(0xFFBDBDBD), width: 0.0)) border: Border(
bottom: BorderSide(
color: Color(0xFFBDBDBD),
width: 0.0,
),
),
), ),
), ),
), ),
...@@ -947,39 +955,73 @@ class DropdownButtonFormField<T> extends FormField<T> { ...@@ -947,39 +955,73 @@ class DropdownButtonFormField<T> extends FormField<T> {
Key key, Key key,
T value, T value,
@required List<DropdownMenuItem<T>> items, @required List<DropdownMenuItem<T>> items,
this.onChanged, Widget hint,
InputDecoration decoration = const InputDecoration(), @required this.onChanged,
this.decoration = const InputDecoration(),
FormFieldSetter<T> onSaved, FormFieldSetter<T> onSaved,
FormFieldValidator<T> validator, FormFieldValidator<T> validator,
Widget hint, bool autovalidate = false,
}) : assert(decoration != null), Widget disabledHint,
int elevation = 8,
TextStyle style,
Widget icon,
Color iconDisabledColor,
Color iconEnabledColor,
double iconSize = 24.0,
bool isDense = false,
bool isExpanded = false,
}) : assert(items == null || items.isEmpty || value == null || items.where((DropdownMenuItem<T> item) => item.value == value).length == 1),
assert(decoration != null),
assert(elevation != null),
assert(iconSize != null),
assert(isDense != null),
assert(isExpanded != null),
super( super(
key: key, key: key,
onSaved: onSaved, onSaved: onSaved,
initialValue: value, initialValue: value,
validator: validator, validator: validator,
autovalidate: autovalidate,
builder: (FormFieldState<T> field) { builder: (FormFieldState<T> field) {
final InputDecoration effectiveDecoration = decoration final InputDecoration effectiveDecoration = decoration.applyDefaults(
.applyDefaults(Theme.of(field.context).inputDecorationTheme); Theme.of(field.context).inputDecorationTheme,
);
return InputDecorator( return InputDecorator(
decoration: effectiveDecoration.copyWith(errorText: field.errorText), decoration: effectiveDecoration.copyWith(errorText: field.errorText),
isEmpty: value == null, isEmpty: value == null,
child: DropdownButtonHideUnderline( child: DropdownButtonHideUnderline(
child: DropdownButton<T>( child: DropdownButton<T>(
isDense: true,
value: value, value: value,
items: items, items: items,
hint: hint, hint: hint,
onChanged: field.didChange, onChanged: onChanged == null ? null : field.didChange,
disabledHint: disabledHint,
elevation: elevation,
style: style,
icon: icon,
iconDisabledColor: iconDisabledColor,
iconEnabledColor: iconEnabledColor,
iconSize: iconSize,
isDense: isDense,
isExpanded: isExpanded,
), ),
), ),
); );
} }
); );
/// Called when the user selects an item. /// {@macro flutter.material.dropdownButton.onChanged}
final ValueChanged<T> onChanged; final ValueChanged<T> onChanged;
/// The decoration to show around the dropdown button form field.
///
/// By default, draws a horizontal line under the dropdown button field but can be
/// configured to show an icon, label, hint text, and error text.
///
/// Specify null to remove the decoration entirely (including the
/// extra padding introduced by the decoration to save space for the labels).
final InputDecoration decoration;
@override @override
FormFieldState<T> createState() => _DropdownButtonFormFieldState<T>(); FormFieldState<T> createState() => _DropdownButtonFormFieldState<T>();
} }
...@@ -991,7 +1033,7 @@ class _DropdownButtonFormFieldState<T> extends FormFieldState<T> { ...@@ -991,7 +1033,7 @@ class _DropdownButtonFormFieldState<T> extends FormFieldState<T> {
@override @override
void didChange(T value) { void didChange(T value) {
super.didChange(value); super.didChange(value);
if (widget.onChanged != null) assert(widget.onChanged != null);
widget.onChanged(value); widget.onChanged(value);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment