🕌
【Flutterエラー】TextFormFieldのキーボードが勝手に閉じる問題と解決策
はじめに
Flutterアプリを開発していると、TextFormField
をタップした際にキーボードがすぐに閉じてしまう問題に遭遇することがあります。
特に、HookWidget
を使っている場合に GlobalKey<FormState>
の管理方法に工夫が必要になるケースがあります。
本記事では、この問題の原因と解決策を簡単に説明します。
問題の発生例
以下のコードでは、HookWidget
を使用し、GlobalKey<FormState>
を変数として定義しています。
sample_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class SampleScreen extends HookWidget {
Widget build(BuildContext context) {
final formKey = GlobalKey<FormState>(); // ここが問題
final textController = useTextEditingController();
return Scaffold(
appBar: AppBar(title: Text('キーボードが閉じる問題')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: formKey.value,
child: Column(
children: [
TextFormField(
controller: textController,
decoration: InputDecoration(labelText: '入力してください'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
if (formKey.value.currentState?.validate() ?? false) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('入力が検証されました')),
);
}
},
child: Text('検証'),
),
],
),
),
),
);
}
}
なぜこのコードでキーボードが閉じてしまうのか?
-
GlobalKey<FormState>()
を単に変数として管理しているため、build
のたびにGlobalKey
が再生成される可能性がある。 -
GlobalKey
が変更されるとForm
が再構築され、フォーカスがリセットされてしまう。
解決策
useMemoized
を使い、GlobalKey<FormState>
を build
のたびに再生成しないようにします。
修正後のコード
sample_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class SampleScreen extends HookWidget {
Widget build(BuildContext context) {
final formKey = useMemoized(() => GlobalKey<FormState>());
final textController = useTextEditingController();
return Scaffold(
appBar: AppBar(title: Text('キーボードが閉じる問題(解決)')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: formKey,
child: Column(
children: [
TextFormField(
controller: textController,
decoration: InputDecoration(labelText: '入力してください'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
if (formKey.currentState?.validate() ?? false) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('入力が検証されました')),
);
}
},
child: Text('検証'),
),
],
),
),
),
);
}
}
変更点
- 変数や
useState
で管理する代わりにuseMemoized
を使用し、GlobalKey<FormState>
を再生成しないようにした。 - これにより、
Form
のGlobalKey
が変わらなくなり、キーボードが勝手に閉じる問題が解消される。
まとめ
HookWidget
を使用する際に GlobalKey<FormState>
を 変数やuseState
で管理すると、キーボードが勝手に閉じる原因になります。useMemoized
を使うことで、GlobalKey
の再生成を防ぎ、安定したフォームの動作を実現できます。
個人的には、今までuseMemoizedを使う機会が少なかったので理解する良い機会となりました。
参考になると嬉しいです!読んでいただき、ありがとうございます!
Discussion