Fix disabled formfield validation (#23167)

* Fix form field validate method being called if form field is disabled
diff --git a/packages/flutter/lib/src/material/text_form_field.dart b/packages/flutter/lib/src/material/text_form_field.dart
index df4d79f..bf2834a 100644
--- a/packages/flutter/lib/src/material/text_form_field.dart
+++ b/packages/flutter/lib/src/material/text_form_field.dart
@@ -71,7 +71,7 @@
     FormFieldSetter<String> onSaved,
     FormFieldValidator<String> validator,
     List<TextInputFormatter> inputFormatters,
-    bool enabled,
+    bool enabled = true,
     Brightness keyboardAppearance,
     EdgeInsets scrollPadding = const EdgeInsets.all(20.0),
   }) : assert(initialValue == null || controller == null),
@@ -90,6 +90,7 @@
     onSaved: onSaved,
     validator: validator,
     autovalidate: autovalidate,
+    enabled: enabled,
     builder: (FormFieldState<String> field) {
       final _TextFormFieldState state = field;
       final InputDecoration effectiveDecoration = (decoration ?? const InputDecoration())
diff --git a/packages/flutter/lib/src/widgets/form.dart b/packages/flutter/lib/src/widgets/form.dart
index ff0d5da..b34d974 100644
--- a/packages/flutter/lib/src/widgets/form.dart
+++ b/packages/flutter/lib/src/widgets/form.dart
@@ -227,6 +227,7 @@
     this.validator,
     this.initialValue,
     this.autovalidate = false,
+    this.enabled = true,
   }) : assert(builder != null),
        super(key: key);
 
@@ -256,6 +257,13 @@
   /// autovalidates, this value will be ignored.
   final bool autovalidate;
 
+  /// Whether the form is able to receive user input.
+  ///
+  /// Defaults to true. If [autovalidate] is true, the field will be validated.
+  /// Likewise, if this field is false, the widget will not be validated
+  /// regardless of [autovalidate].
+  final bool enabled;
+
   @override
   FormFieldState<T> createState() => FormFieldState<T>();
 }
@@ -344,7 +352,8 @@
 
   @override
   Widget build(BuildContext context) {
-    if (widget.autovalidate)
+    // Only autovalidate if the widget is also enabled
+    if (widget.autovalidate && widget.enabled)
       _validate();
     Form.of(context)?._register(this);
     return widget.builder(this);
diff --git a/packages/flutter/test/material/text_form_field_test.dart b/packages/flutter/test/material/text_form_field_test.dart
index b80e155..4ad6c40 100644
--- a/packages/flutter/test/material/text_form_field_test.dart
+++ b/packages/flutter/test/material/text_form_field_test.dart
@@ -114,4 +114,52 @@
     await tester.pump();
     expect(_validateCalled, 2);
   });
+
+  testWidgets('validate is not called if widget is disabled', (WidgetTester tester) async {
+    int _validateCalled = 0;
+
+    await tester.pumpWidget(
+      MaterialApp(
+        home: Material(
+          child: Center(
+            child: TextFormField(
+              enabled: false,
+              autovalidate: true,
+              validator: (String value) { _validateCalled += 1; return null; },
+            ),
+          ),
+        ),
+      ),
+    );
+
+    expect(_validateCalled, 0);
+    await tester.showKeyboard(find.byType(TextField));
+    await tester.enterText(find.byType(TextField), 'a');
+    await tester.pump();
+    expect(_validateCalled, 0);
+  });
+
+  testWidgets('validate is called if widget is enabled', (WidgetTester tester) async {
+    int _validateCalled = 0;
+
+    await tester.pumpWidget(
+      MaterialApp(
+        home: Material(
+          child: Center(
+            child: TextFormField(
+              enabled: true,
+              autovalidate: true,
+              validator: (String value) { _validateCalled += 1; return null; },
+            ),
+          ),
+        ),
+      ),
+    );
+
+    expect(_validateCalled, 1);
+    await tester.showKeyboard(find.byType(TextField));
+    await tester.enterText(find.byType(TextField), 'a');
+    await tester.pump();
+    expect(_validateCalled, 2);
+  });
 }