diff --git a/packages/flutter/lib/src/material/dropdown.dart b/packages/flutter/lib/src/material/dropdown.dart index 2cedb414fe2..d13a90ef559 100644 --- a/packages/flutter/lib/src/material/dropdown.dart +++ b/packages/flutter/lib/src/material/dropdown.dart @@ -1427,19 +1427,20 @@ class DropdownButtonFormField extends FormField { validator: validator, autovalidate: autovalidate, builder: (FormFieldState field) { + final _DropdownButtonFormFieldState state = field as _DropdownButtonFormFieldState; final InputDecoration effectiveDecoration = decoration.applyDefaults( Theme.of(field.context).inputDecorationTheme, ); return InputDecorator( decoration: effectiveDecoration.copyWith(errorText: field.errorText), - isEmpty: value == null, + isEmpty: state.value == null, child: DropdownButtonHideUnderline( child: DropdownButton( - value: value, + value: state.value, items: items, selectedItemBuilder: selectedItemBuilder, hint: hint, - onChanged: onChanged == null ? null : field.didChange, + onChanged: onChanged == null ? null : state.didChange, disabledHint: disabledHint, elevation: elevation, style: style, diff --git a/packages/flutter/test/material/dropdown_test.dart b/packages/flutter/test/material/dropdown_test.dart index 795822c42c4..e00add869dd 100644 --- a/packages/flutter/test/material/dropdown_test.dart +++ b/packages/flutter/test/material/dropdown_test.dart @@ -360,6 +360,63 @@ void main() { } }); + testWidgets('Dropdown form field uses form field state', (WidgetTester tester) async { + final Key buttonKey = UniqueKey(); + final GlobalKey formKey = GlobalKey(); + String value; + await tester.pumpWidget( + StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return MaterialApp( + home: Material( + child: Form( + key: formKey, + child: DropdownButtonFormField( + key: buttonKey, + value: value, + hint: const Text('Select Value'), + decoration: const InputDecoration( + prefixIcon: Icon(Icons.fastfood) + ), + items: menuItems.map((String val) { + return DropdownMenuItem( + value: val, + child: Text(val) + ); + }).toList(), + validator: (String v) => v == null ? 'Must select value' : null, + onChanged: (String newValue) {}, + onSaved: (String v) { + setState(() { + value = v; + }); + }, + ), + ), + ), + ); + } + ) + ); + int getIndex() { + final IndexedStack stack = tester.element(find.byType(IndexedStack)).widget as IndexedStack; + return stack.index; + } + // Initial value of null displays hint + expect(value, equals(null)); + expect(getIndex(), 4); + await tester.tap(find.text('Select Value')); + await tester.pumpAndSettle(); + await tester.tap(find.text('three').last); + await tester.pumpAndSettle(); + expect(getIndex(), 2); + // Changes only made to FormField state until form saved + expect(value, equals(null)); + final FormState form = formKey.currentState; + form.save(); + expect(value, equals('three')); + }); + testWidgets('Dropdown in ListView', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/12053 // Positions a DropdownButton at the left and right edges of the screen,