How to listen focus change in flutter?
In Android, we can call setOnFocusChangeListener()
, do something in onFocusChanged()
method, but flutter does not provider onFocus()
interface like onTap()
in GestureDetector or onKey()
in RawKeyboardListener.
I have read flutter api about focus, https://docs.flutter.io/flutter/widgets/FocusManager-class.html but I can't find a way to realize my request, anyone who can give me a hand?
Solution 1:
In addtion you can use Focus widget.
Focus(
child: TextFormField(...),
onFocusChange: (hasFocus) {
if(hasFocus) {
// do stuff
}
},
)
Solution 2:
Using FocusNode
Here is a fully correct answer. addListener
shall be in initState()
, not build()
, because that would result in adding a listener every time a widget is built and you most likely don't want that.
import 'package:flutter/material.dart';
class SomeWidget extends StatefulWidget {
@override
_SomeWidgetState createState() => _SomeWidgetState();
}
class _SomeWidgetState extends State<SomeWidget> {
final _focusNode = FocusNode();
@override
void initState() {
super.initState();
_focusNode.addListener(() {
print("Has focus: ${_focusNode.hasFocus}");
});
}
@override
Widget build(BuildContext context) {
return TextField(focusNode: _focusNode);
}
@override
void dispose() {
_focusNode.dispose();
super.dispose();
}
}
Using flutter_hooks
package
If you're by any chance using the flutter_hooks package, there is a dedicated useFocusNode
hook.
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class SomeWidget extends HookWidget {
@override
Widget build(BuildContext context) {
final focusNode = useFocusNode();
useEffect(() {
focusNode.addListener(() {
print("Has focus: ${focusNode.hasFocus}");
});
return; // You need this return if you have missing_return lint
}, [focusNode]);
return TextField(focusNode: focusNode);
}
}