How to detect when a TextField is selected in Flutter?
KeyboardTextfieldFlutterKeyboard Problem Overview
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.
Keyboard Solutions
Solution 1 - Keyboard
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 - Keyboard
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 - Keyboard
The easiest and simplest solution is to add the onTap method on TextField.
TextField(
onTap: () {
print('Editing stated $widget');
},
)
Solution 4 - Keyboard
Simply use onTap
function of TextField
.
TextField(
onTap: () {
// Your code.
},
);
Solution 5 - Keyboard
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,
),
);