How to detect when a TextField is selected in Flutter?
Solution 1
I suppose you are looking for FocusNode
.
To listen to focus change, you can add a listner to the FocusNode
and specify the focusNode
to TextField
.
Example:
class TextFieldFocus extends StatefulWidget {
@override
_TextFieldFocusState createState() => _TextFieldFocusState();
}
class _TextFieldFocusState extends State<TextFieldFocus> {
FocusNode _focus = FocusNode();
TextEditingController _controller = TextEditingController();
@override
void initState() {
super.initState();
_focus.addListener(_onFocusChange);
}
@override
void dispose() {
super.dispose();
_focus.removeListener(_onFocusChange);
_focus.dispose();
}
void _onFocusChange() {
debugPrint("Focus: ${_focus.hasFocus.toString()}");
}
@override
Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: new TextField(
focusNode: _focus,
),
);
}
}
This gist represents how to ensure a focused node to be visible on the ui.
Hope it helps!
Solution 2
To be notified about a focus event, you can avoid manually managing widget's state, by using the utility classes FocusScope
, Focus
.
From the docs (https://api.flutter.dev/flutter/widgets/FocusNode-class.html):
Please see the Focus and FocusScope widgets, which are utility widgets that manage their own FocusNodes and FocusScopeNodes, respectively. If they aren't appropriate, FocusNodes can be managed directly.
Here is a simple example:
FocusScope(
child: Focus(
onFocusChange: (focus) => print("focus: $focus"),
child: TextField(
decoration: const InputDecoration(labelText: 'City'),
)
)
)
Solution 3
The easiest and simplest solution is to add the onTap method on TextField.
TextField(
onTap: () {
print('Editing stated $widget');
},
)
Solution 4
Simply use onTap
function of TextField
.
TextField(
onTap: () {
// Your code.
},
);
Solution 5
There is another way if your textfield needs to be disabled for some purpose like mine. for that case, you can wrap your textField with InkWell
like this,
InkWell(
onTap: () {
print('clicked');
},
child: TextField(
enabled: false,
),
);
user2785693
Retired professionally but still tinker with code.
Updated on January 07, 2022Comments
-
user2785693 over 2 years
I have a Flutter TextField which gets covered by the soft keyboard when the field is selected. I need to scroll the field up and out of the way when the keyboard is displayed. This is a pretty common problem and a solution is presented in this StackOverflow post.
I think I have the ScrollController part figured out but how do I detect when the TextField has been selected? There doesn't appear to be any event method (e.g. onFocus(), onSelected(), onTap(), etc).
I tried wrapping the TextField in a GestureDetector but that didn't work either -- apparently the event was never captured.
new GestureDetector( child: new TextField( decoration: const InputDecoration(labelText: 'City'), ), onTap: () => print('Text Selected'), ),
This is such a basic requirement that I know there must be an easy solution.
-
user2785693 about 6 yearsThank you so very much for this answer. I haven't attempted to utilize the more robust solution you offered in the gist but the simple solution below seems to work in my test case.
-
Qiong Wu about 6 yearsI have an issue with this solution, since I am showing an overlay on focusing the textfield. showing the overlay works like a charm, but as soon as the overlay is closed, the textfield is autofocused again, and the overlay pops up again
-
Hemanth Raj about 6 yearsbefore showing the dialog just invoke
unfocus
method on the same focus node. Do it only if you did not wanted the textfield to be focused when you come back. -
Günter Zöchbauer about 5 yearsThere are other means for a TextField to get focus, for example if it's the first
TextField
on a page and future Flutter versions will support tabbing through fields. -
Renan Coelho over 4 yearsSaved me! Thank you!
-
Ryan R about 4 yearsSimple and concise.
-
stpch about 4 yearsThe focus node should also be cleaned up in the stateful widget's dispose(). See the example on api.flutter.dev/flutter/widgets/FocusNode-class.html.
-
Hesam over 3 yearsdon't forget to dispose it in dispose();
-
Eradicatore about 3 yearsGreat answer, thanks. I do see though, if I advance the focus to the next text field with node.nextFocus() then I don't have access to the controller for the next field to set the selection like I do with your onTap() solution. hmmm
-
Iosif Pop about 3 yearsGreat answer. Thanks!
-
TGLEE about 3 yearsFor me, this answer worked better than the accepted answer because the callback gets called only when the child widget 'TextField' is tapped for entering text. With 'addListener' method from the accpepted answer, it was not the case. Some of parents widget would trigger the callback too when tapped. I didn't quite understand why..
-
Marwin Lebensky almost 3 yearsOn android, if you press the system backbutton while in a TextField then [onFocusChange] will not be triggered.
-
Harini Sampath over 2 years_focus.removeListner, and _focus.dispose in the dispose()
-
Yogi Arif Widodo over 2 yearsbut when we trigger a popup the focuscope trigger against on focus, so my datepicker open against.