@@ -157,6 +157,7 @@ class CupertinoTextFormFieldRow extends FormField<String> {
157
157
color: CupertinoColors .placeholderText,
158
158
),
159
159
EditableTextContextMenuBuilder ? contextMenuBuilder = _defaultContextMenuBuilder,
160
+ super .restorationId,
160
161
}) : assert (initialValue == null || controller == null ),
161
162
assert (obscuringCharacter.length == 1 ),
162
163
assert (maxLines == null || maxLines > 0 ),
@@ -186,50 +187,54 @@ class CupertinoTextFormFieldRow extends FormField<String> {
186
187
prefix: prefix,
187
188
padding: padding,
188
189
error: (field.errorText == null ) ? null : Text (field.errorText! ),
189
- child: CupertinoTextField .borderless (
190
- controller: state._effectiveController,
191
- focusNode: focusNode,
192
- keyboardType: keyboardType,
193
- decoration: decoration,
194
- textInputAction: textInputAction,
195
- style: style,
196
- strutStyle: strutStyle,
197
- textAlign: textAlign,
198
- textAlignVertical: textAlignVertical,
199
- textCapitalization: textCapitalization,
200
- textDirection: textDirection,
201
- autofocus: autofocus,
202
- toolbarOptions: toolbarOptions,
203
- readOnly: readOnly,
204
- showCursor: showCursor,
205
- obscuringCharacter: obscuringCharacter,
206
- obscureText: obscureText,
207
- autocorrect: autocorrect,
208
- smartDashesType: smartDashesType,
209
- smartQuotesType: smartQuotesType,
210
- enableSuggestions: enableSuggestions,
211
- maxLines: maxLines,
212
- minLines: minLines,
213
- expands: expands,
214
- maxLength: maxLength,
215
- onChanged: onChangedHandler,
216
- onTap: onTap,
217
- onEditingComplete: onEditingComplete,
218
- onSubmitted: onFieldSubmitted,
219
- inputFormatters: inputFormatters,
220
- enabled: enabled ?? true ,
221
- cursorWidth: cursorWidth,
222
- cursorHeight: cursorHeight,
223
- cursorColor: cursorColor,
224
- scrollPadding: scrollPadding,
225
- scrollPhysics: scrollPhysics,
226
- keyboardAppearance: keyboardAppearance,
227
- enableInteractiveSelection: enableInteractiveSelection,
228
- selectionControls: selectionControls,
229
- autofillHints: autofillHints,
230
- placeholder: placeholder,
231
- placeholderStyle: placeholderStyle,
232
- contextMenuBuilder: contextMenuBuilder,
190
+ child: UnmanagedRestorationScope (
191
+ bucket: field.bucket,
192
+ child: CupertinoTextField .borderless (
193
+ restorationId: restorationId,
194
+ controller: state._effectiveController,
195
+ focusNode: focusNode,
196
+ keyboardType: keyboardType,
197
+ decoration: decoration,
198
+ textInputAction: textInputAction,
199
+ style: style,
200
+ strutStyle: strutStyle,
201
+ textAlign: textAlign,
202
+ textAlignVertical: textAlignVertical,
203
+ textCapitalization: textCapitalization,
204
+ textDirection: textDirection,
205
+ autofocus: autofocus,
206
+ toolbarOptions: toolbarOptions,
207
+ readOnly: readOnly,
208
+ showCursor: showCursor,
209
+ obscuringCharacter: obscuringCharacter,
210
+ obscureText: obscureText,
211
+ autocorrect: autocorrect,
212
+ smartDashesType: smartDashesType,
213
+ smartQuotesType: smartQuotesType,
214
+ enableSuggestions: enableSuggestions,
215
+ maxLines: maxLines,
216
+ minLines: minLines,
217
+ expands: expands,
218
+ maxLength: maxLength,
219
+ onChanged: onChangedHandler,
220
+ onTap: onTap,
221
+ onEditingComplete: onEditingComplete,
222
+ onSubmitted: onFieldSubmitted,
223
+ inputFormatters: inputFormatters,
224
+ enabled: enabled ?? true ,
225
+ cursorWidth: cursorWidth,
226
+ cursorHeight: cursorHeight,
227
+ cursorColor: cursorColor,
228
+ scrollPadding: scrollPadding,
229
+ scrollPhysics: scrollPhysics,
230
+ keyboardAppearance: keyboardAppearance,
231
+ enableInteractiveSelection: enableInteractiveSelection,
232
+ selectionControls: selectionControls,
233
+ autofillHints: autofillHints,
234
+ placeholder: placeholder,
235
+ placeholderStyle: placeholderStyle,
236
+ contextMenuBuilder: contextMenuBuilder,
237
+ ),
233
238
),
234
239
);
235
240
},
@@ -272,19 +277,45 @@ class CupertinoTextFormFieldRow extends FormField<String> {
272
277
}
273
278
274
279
class _CupertinoTextFormFieldRowState extends FormFieldState <String > {
275
- TextEditingController ? _controller;
280
+ RestorableTextEditingController ? _controller;
276
281
277
- TextEditingController ? get _effectiveController =>
278
- _cupertinoTextFormFieldRow.controller ?? _controller;
282
+ TextEditingController get _effectiveController =>
283
+ _cupertinoTextFormFieldRow.controller ?? _controller! .value ;
279
284
280
285
CupertinoTextFormFieldRow get _cupertinoTextFormFieldRow =>
281
286
super .widget as CupertinoTextFormFieldRow ;
282
287
288
+ @override
289
+ void restoreState (RestorationBucket ? oldBucket, bool initialRestore) {
290
+ super .restoreState (oldBucket, initialRestore);
291
+ if (_controller != null ) {
292
+ _registerController ();
293
+ }
294
+ // This makes sure to update the internal [FormFieldState] value to sync up with
295
+ // text editing controller value.
296
+ setValue (_effectiveController.text);
297
+ }
298
+
299
+ void _registerController () {
300
+ assert (_controller != null );
301
+ registerForRestoration (_controller! , 'controller' );
302
+ }
303
+
304
+ void _createLocalController ([TextEditingValue ? value]) {
305
+ assert (_controller == null );
306
+ _controller = value == null
307
+ ? RestorableTextEditingController ()
308
+ : RestorableTextEditingController .fromValue (value);
309
+ if (! restorePending) {
310
+ _registerController ();
311
+ }
312
+ }
313
+
283
314
@override
284
315
void initState () {
285
316
super .initState ();
286
317
if (_cupertinoTextFormFieldRow.controller == null ) {
287
- _controller = TextEditingController (text: widget.initialValue);
318
+ _createLocalController (widget.initialValue != null ? TextEditingValue (text: widget.initialValue! ) : null );
288
319
} else {
289
320
_cupertinoTextFormFieldRow.controller! .addListener (_handleControllerChanged);
290
321
}
@@ -298,13 +329,14 @@ class _CupertinoTextFormFieldRowState extends FormFieldState<String> {
298
329
_cupertinoTextFormFieldRow.controller? .addListener (_handleControllerChanged);
299
330
300
331
if (oldWidget.controller != null && _cupertinoTextFormFieldRow.controller == null ) {
301
- _controller =
302
- TextEditingController .fromValue (oldWidget.controller! .value);
332
+ _createLocalController (oldWidget.controller! .value);
303
333
}
304
334
305
335
if (_cupertinoTextFormFieldRow.controller != null ) {
306
336
setValue (_cupertinoTextFormFieldRow.controller! .text);
307
337
if (oldWidget.controller == null ) {
338
+ unregisterFromRestoration (_controller! );
339
+ _controller! .dispose ();
308
340
_controller = null ;
309
341
}
310
342
}
@@ -322,18 +354,18 @@ class _CupertinoTextFormFieldRowState extends FormFieldState<String> {
322
354
void didChange (String ? value) {
323
355
super .didChange (value);
324
356
325
- if (value != null && _effectiveController! .text != value) {
326
- _effectiveController! .text = value;
357
+ if (value != null && _effectiveController.text != value) {
358
+ _effectiveController.text = value;
327
359
}
328
360
}
329
361
330
362
@override
331
363
void reset () {
332
364
// Set the controller value before calling super.reset() to let
333
365
// _handleControllerChanged suppress the change.
334
- _effectiveController! .text = widget.initialValue! ;
366
+ _effectiveController.text = widget.initialValue! ;
335
367
super .reset ();
336
- _cupertinoTextFormFieldRow.onChanged? .call (_effectiveController! .text);
368
+ _cupertinoTextFormFieldRow.onChanged? .call (_effectiveController.text);
337
369
}
338
370
339
371
void _handleControllerChanged () {
@@ -344,8 +376,8 @@ class _CupertinoTextFormFieldRowState extends FormFieldState<String> {
344
376
// notifications for changes originating from within this class -- for
345
377
// example, the reset() method. In such cases, the FormField value will
346
378
// already have been set.
347
- if (_effectiveController! .text != value) {
348
- didChange (_effectiveController! .text);
379
+ if (_effectiveController.text != value) {
380
+ didChange (_effectiveController.text);
349
381
}
350
382
}
351
383
}
0 commit comments