先日、キーボードの表示状態を検知しなくてはならない状況に遭遇しました。
検知は flutter_keyboard_visibility を用いて簡単に行うことができます。いくつかの実装が用意されていますが、ここでは Direct query and subscription の実装を使用します。
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'dart:async'; late StreamSubscription<bool> keyboardSubscription; @override void initState() { super.initState(); var keyboardVisibilityController = KeyboardVisibilityController(); // Query print('Keyboard visibility direct query: ${keyboardVisibilityController.isVisible}'); // Subscribe keyboardSubscription = keyboardVisibilityController.onChange.listen((bool visible) { print('Keyboard visibility update. Is visible: $visible'); }); } @override void dispose() { keyboardSubscription.cancel(); super.dispose(); }
ただ、このサンプルを見て、「これは カスタムフックにできるのでは?」と思い実装してみました。
こちらがそのカスタムフックの実装です。
/// キーボードの表示状態を取得する Hook bool useKeyboardVisibility() { return use(const _KeyboardVisibility()); } class _KeyboardVisibility extends Hook<bool> { const _KeyboardVisibility(); @override _KeyboardVisibilityState createState() => _KeyboardVisibilityState(); } class _KeyboardVisibilityState extends HookState<bool, _KeyboardVisibility> { late final KeyboardVisibilityController _controller; late final StreamSubscription<bool> _subscription; @override void initHook() { super.initHook(); _controller = KeyboardVisibilityController(); _subscription = _controller.onChange.listen((_) { // build を発火させる setState(() {}); }); } @override bool build(BuildContext context) { return _controller.isVisible; } @override void dispose() { _subscription.cancel(); super.dispose(); } }
また、これをもっと使いやすく、キーボードを閉じた場合に限定したものも作ってみました。
/// キーボードが非表示になった時にコールバックを呼び出す Hook void useOnKeyboardHidden(VoidCallback callback) { final keyboardVisibility = useKeyboardVisibility(); useEffect( () { if (!keyboardVisibility) { callback(); } return null; }, [keyboardVisibility], ); }
今回は StreamSubscription を用いる形のものからカスタムフックを作成してみました。これまで flutter_hooks 組み込みのフックを組み合わせた関数のカスタムフックは何度か作成したことがありますが、クラスのカスタムフックは初めてだったので最初は戸惑いました。いい具合に作成できた気がします。
もっといい実装あるよ!これじゃあ、〇〇の場合に動かないよ!といったご意見、ご指摘ありましたら、是非ともコメントください。