Skip to content

Instantly share code, notes, and snippets.

@lukepighetti
Last active September 27, 2021 20:32
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save lukepighetti/55d367808e994e426fc0c7f7032fab9c to your computer and use it in GitHub Desktop.
Save lukepighetti/55d367808e994e426fc0c7f7032fab9c to your computer and use it in GitHub Desktop.
Wrap any TextField with TextEditingControllerBuilder to make it declarative
import 'package:flutter/widgets.dart';
class TextEditingControllerBuilder extends StatefulWidget {
/// Exposes a [TextEditingController] to the child, which allows
/// us to convert any [TextField] into a declarative version.
///
/// Typically used for wiring up many state fields to form inputs
/// and making sure everything stays in sync.
///
/// If [text] is updated, the consuming [TextField] will also be updated.
/// If the ancestor is rebuilt, the composing state will not be lost like it typically is.
///
/// ```dart
/// TextEditingControllerBuilder(
/// text: appState.name,
/// builder: (context, controller) {
/// return TextField(
/// controller: controller,
/// onChanged: (value) => appState.updateName(value),
/// );
/// },
/// );
/// ```
const TextEditingControllerBuilder({
Key key,
@required this.text,
@required this.builder,
}) : super(key: key);
/// The text to declaratively update in the text controller
final String text;
/// The builder which exposes the [TextEditingController] to the child
final Widget Function(BuildContext, TextEditingController) builder;
@override
_TextEditingControllerBuilderState createState() =>
_TextEditingControllerBuilderState();
}
class _TextEditingControllerBuilderState
extends State<TextEditingControllerBuilder> {
TextEditingController controller;
@override
void initState() {
controller = TextEditingController(text: widget.text);
super.initState();
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
@override
void didUpdateWidget(covariant TextEditingControllerBuilder oldWidget) {
if (oldWidget.text != widget.text) {
controller.value = controller.value.copyWith(text: widget.text);
}
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return widget.builder(context, controller);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment