I'm new in Flutter and I am following this official example about text fields: https://flutter.dev/docs/cookbook/forms/text-field-changes
There is an axample for listen to changes in the controller of a text field widget. Please note this fragment of code _MyCustomFormState
final myController = TextEditingController();
@override
void initState() {
super.initState();
myController.addListener(_printLatestValue);
}
_printLatestValue() {
print("Second text field: ${myController.text}");
}
If I have two fields and two controllers, I would like to have just one listener, and display some message depending on which controller called the method. I would like to do something like this:
final myController1 = TextEditingController();
final myController2 = TextEditingController();
@override
void initState() {
super.initState();
myController1.addListener(_printLatestValue('message1'));
myController1.addListener(_printLatestValue('message2'));
}
_printLatestValue(message) {
print("Second text field: ${myController.text + message}");
}
which is not possible because the method addListener() uses some called VoidCallback, which have no arguments. At least that is what I understood from the Flutter docs.
So, if it is possible, how can I achieve what I'm looking for?
You're almost correct, but not quite. You're free to pass in any arguments to the listener. However, those arguments need to come from somewhere else - TextEditingController does not supply any, and it does not expect any return values. In other words, the signature should be something like: () => listener(...).
So to answer your question, you're free to do something like the following to distinguish the controllers:
void initState() {
super.initState();
firstController.addListener(() => _printLatestValue('first'));
secondController.addListener(() => _printLatestValue('second'));
}
Full working example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Text controllers',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final firstController = TextEditingController();
final secondController = TextEditingController();
void initState() {
super.initState();
firstController.addListener(() => _printLatestValue('first'));
secondController.addListener(() => _printLatestValue('second'));
}
@override
void dispose() {
firstController.dispose();
secondController.dispose();
super.dispose();
}
_printLatestValue(message) {
if (message == 'first') {
print('Received form first controller: ${firstController.text}');
} else {
print('Received from second controller: ${secondController.text}');
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Controllers', style: TextStyle(fontSize: 18)),
),
body: Center(
child: Column(
children: <Widget>[
TextField(controller: firstController,),
TextField(controller: secondController,)
],
),
),
);
}
}
Note that in this case, listener will only print the text from a TextField that was changed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With