diff --git a/packages/flutter/lib/src/widgets/form.dart b/packages/flutter/lib/src/widgets/form.dart index 3989da3ea4..cb8b5d9c6e 100644 --- a/packages/flutter/lib/src/widgets/form.dart +++ b/packages/flutter/lib/src/widgets/form.dart @@ -524,6 +524,8 @@ class FormFieldState extends State> with RestorationMixin { void _validate() { if (widget.validator != null) { _errorText.value = widget.validator!(_value); + } else { + _errorText.value = null; } } diff --git a/packages/flutter/test/widgets/form_test.dart b/packages/flutter/test/widgets/form_test.dart index 90f5fe727b..6d2996c723 100644 --- a/packages/flutter/test/widgets/form_test.dart +++ b/packages/flutter/test/widgets/form_test.dart @@ -945,4 +945,71 @@ void main() { fieldKey.currentState!.reset(); expect(fieldKey.currentState!.hasInteractedByUser, isFalse); }); + + testWidgets('Validator is nullified and error text behaves accordingly', + (WidgetTester tester) async { + final GlobalKey formKey = GlobalKey(); + bool useValidator = false; + late StateSetter setState; + + String? validator(String? value) { + if (value == null || value.isEmpty) { + return 'test_error'; + } + return null; + } + + Widget builder() { + return StatefulBuilder( + builder: (BuildContext context, StateSetter setter) { + setState = setter; + return MaterialApp( + home: MediaQuery( + data: const MediaQueryData(), + child: Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: Material( + child: Form( + key: formKey, + child: TextFormField( + validator: useValidator ? validator : null, + ), + ), + ), + ), + ), + ), + ); + }, + ); + } + + await tester.pumpWidget(builder()); + + // Start with no validator. + await tester.enterText(find.byType(TextFormField), ''); + await tester.pump(); + formKey.currentState!.validate(); + await tester.pump(); + expect(find.text('test_error'), findsNothing); + + // Now use the validator. + setState(() { + useValidator = true; + }); + await tester.pump(); + formKey.currentState!.validate(); + await tester.pump(); + expect(find.text('test_error'), findsOneWidget); + + // Remove the validator again and expect the error to disappear. + setState(() { + useValidator = false; + }); + await tester.pump(); + formKey.currentState!.validate(); + await tester.pump(); + expect(find.text('test_error'), findsNothing); + }); }