I want to hide screen keyboard by onTap outside TextField
or anywhere on screen.
Then i wrap my Scaffold
with GestureDetector
like below.
i already try both with onTap
and onTapDown
.
GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (_) {
printLog("hide keyboard ${_.localPosition}");
FocusManager.instance.primaryFocus?.unfocus();
},
child: Scaffold()
Everything work fine on simple widget (small amount of widget ). But when i have much widget rendered, the function to hide keyboard only called sometimes. not every action ontap Happend on my screen.
eg in my scaffold body:
ListView.builder(
itemCount: 50,
itemBuilder: ((context, index) => GestureDetector(
onTap: () {
printLog("tap on card");
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 3),
height: 60,
color: Colors.blueGrey,
),)))
here the console log.
as we can see (line 4) , the print('[Debug] hide keyboard Offset()')
do not called every onTap()
happend on my screen.
I/flutter (15284): [Debug] hide keyboard Offset(281.5, 330.2)
(2)I/flutter (15284): [Debug] tap on card
I/flutter (15284): [Debug] hide keyboard Offset(253.5, 292.0)
(3)I/flutter (15284): [Debug] tap on card => i tapped 3 times on my card
I/flutter (15284): [Debug] tap on card => until the 4th tap, keybord not hide
I/flutter (15284): [Debug] hide keyboard Offset(186.2, 279.3)
I/flutter (15284): [Debug] tap on card
but when i do longpress
on my card, the function hide keyboard always will be called.
i assume there is a delay on GestureDetector
while catching the onTap. so user need to tap longer than usual. But its not good thing, because i cant tell the user to press longer on screen everytime use the app.
.
.
what i want to achieve is, every clicking outside of my
Textfield
, it should called hide keyboard function without delayed.
we can use a new property named onTapOutside
. No need to wrap all widgets with GestureDetector
TextFormField(
onTapOutside: (event) =>
FocusManager.instance.primaryFocus?.unfocus(),
controller: _ctrl,
reff: https://stackoverflow.com/a/53063398/12838877
so i change the GestureDetector
to Listener
. it more faster.
documentation said:
Rather than listening for raw pointer events, consider listening for higher-level gestures using GestureDetector.
and its works fine as expected now.
@override
Widget build(BuildContext context) {
return Listener(
behavior: HitTestBehavior.opaque,
onPointerDown: (_) {
printLog("hide keyboard ${_.localPosition}");
FocusManager.instance.primaryFocus?.unfocus();
},
child: Scaffold()