This tutorial shows you how to detect the visibility of the on-screen keyboard in Flutter, whether it's open or closed.
When an application is running, there can be a soft keyboard displayed on the screen, typically when the user is editing a field. Sometimes, an application may need to detect whether the keyboard is visible or not. In this tutorial, I'm going to show you how to do it in Flutter by using a third party package.
Using flutter_keyboard_visibility
There is a plugin named flutter_keyboard_visibility
that provides the capability to detect whether the keyboard is open or closed. You need to add it as a dependency
flutter pub add flutter_keyboard_visibility
Then, you can use it by adding the following import statement.
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
The library provides some different ways to get the visibility of the keyboard as shown below.
Using KeyboardVisibilityBuilder
First, you can use a class named KeyboardVisibilityBuilder
. It requires you to pass a function as the builder
argument which will be invoked when the keyboard visibility changes. The passed function must return a widget and accept two parameters whose types in order are BuildContext
and bool
. The latter indicates that the keyboard is visible if the value is true
.
class Example1 extends StatelessWidget {
const Example1({super.key});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
const TextField(),
const SizedBox(height: 20.0),
KeyboardVisibilityBuilder(
builder: (BuildContext context, bool isKeyboardVisible) {
return Text('Is Visible: $isKeyboardVisible');
},
),
],
),
);
}
}
Using KeyboardVisibilityProvider
Another way is using the KeyboardVisibilityProvider
widget. It's a widget that can report to its descendants whether the keyboard is visible. This way, you have to add a KeyboardVisibilityProvider
widget with another widget as the child. When the keyboard visibility changes, the child widget will be rebuilt. In the child widget that's below KeyboardVisibilityProvider
in the tree, you can call isKeyboardVisible
method by passing the current BuildContext
.
class Example2 extends StatelessWidget {
const Example2({super.key});
@override
Widget build(BuildContext context) {
return const KeyboardVisibilityProvider(
child: MyWidget(),
);
}
}
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
final bool isKeyboardVisible = KeyboardVisibilityProvider.isKeyboardVisible(context);
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
const TextField(),
const SizedBox(height: 20.0),
Text('Is Visible: $isKeyboardVisible'),
],
),
);
}
}
Using KeyboardVisibilityController
Another alternative is to use a KeyboardVisibilityController
, which allows you to pass one or more functions as listeners. First, you need to create an instance of it. To get the initial state, access the isVisible
property of the instance.
The KeyboardVisibilityController
has onChange
getter which returns a Stream
. Then, you can call the Stream
's listen
method to pass a listener function. The passed function needs to have one parameter, in this case a bool
whose value is true
if the keyboard is opened or false
otherwise. Every time the keyboard becomes visible or hidden, the function will be invoked. In the example below, the passed function updates a state variable when it's invoked.
class Example3 extends StatefulWidget {
const Example3({super.key});
@override
State<StatefulWidget> createState() {
return _Example3State();
}
}
class _Example3State extends State<Example3> {
late StreamSubscription<bool> _subscription; // import 'dart:async';
late bool _isKeyboardVisible;
@override
void initState() {
super.initState();
final keyboardVisibilityController = KeyboardVisibilityController();
_isKeyboardVisible = keyboardVisibilityController.isVisible;
_subscription = keyboardVisibilityController.onChange.listen((bool isKeyboardVisible) {
setState(() {
_isKeyboardVisible = isKeyboardVisible;
});
});
}
@override
void dispose() {
_subscription.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
const TextField(),
const SizedBox(height: 20.0),
Text('Is Visible: $_isKeyboardVisible'),
],
),
);
}
}
Summary
If you need to detect the keyboard visibility when a Flutter application runs, you can use the functionality provided by flutter_keyboard_visibility
. The package has several ways to do it. Keep in mind that, it may not be able to detect that a floating keyboard is shown.