Added onChanged property to TextFormField (#34932)

diff --git a/packages/flutter/lib/src/material/text_form_field.dart b/packages/flutter/lib/src/material/text_form_field.dart
index f111b77..cea1bf9 100644
--- a/packages/flutter/lib/src/material/text_form_field.dart
+++ b/packages/flutter/lib/src/material/text_form_field.dart
@@ -98,6 +98,7 @@
     int minLines,
     bool expands = false,
     int maxLength,
+    ValueChanged<String> onChanged,
     VoidCallback onEditingComplete,
     ValueChanged<String> onFieldSubmitted,
     FormFieldSetter<String> onSaved,
@@ -144,6 +145,12 @@
       final _TextFormFieldState state = field;
       final InputDecoration effectiveDecoration = (decoration ?? const InputDecoration())
         .applyDefaults(Theme.of(field.context).inputDecorationTheme);
+      void onChangedHandler(String value) {
+        if (onChanged != null) {
+          onChanged(value);
+        }
+        field.didChange(value);
+      }
       return TextField(
         controller: state._effectiveController,
         focusNode: focusNode,
@@ -165,7 +172,7 @@
         minLines: minLines,
         expands: expands,
         maxLength: maxLength,
-        onChanged: field.didChange,
+        onChanged: onChangedHandler,
         onEditingComplete: onEditingComplete,
         onSubmitted: onFieldSubmitted,
         inputFormatters: inputFormatters,
diff --git a/packages/flutter/test/material/text_form_field_test.dart b/packages/flutter/test/material/text_form_field_test.dart
index 8fefc44..8fe21d6 100644
--- a/packages/flutter/test/material/text_form_field_test.dart
+++ b/packages/flutter/test/material/text_form_field_test.dart
@@ -123,6 +123,28 @@
     expect(_called, true);
   });
 
+  testWidgets('onChanged callbacks are called', (WidgetTester tester) async {
+    String _value;
+
+    await tester.pumpWidget(
+      MaterialApp(
+        home: Material(
+          child: Center(
+            child: TextFormField(
+              onChanged: (String value) {
+                _value = value;
+              },
+            ),
+          ),
+        ),
+      ),
+    );
+
+    await tester.enterText(find.byType(TextField), 'Soup');
+    await tester.pump();
+    expect(_value, 'Soup');
+  });
+
   testWidgets('autovalidate is passed to super', (WidgetTester tester) async {
     int _validateCalled = 0;