Flutter入門

【5分で分かる】キーボードを閉じる3つの方法 | Flutter入門


ども、木村です。本業はデータサイエンティスト、副業でアプリ開発をしています。

本記事は、Flutter開発におけるキーボードを閉じる3つの方法を解説します。

想定読者

Flutterにおけるキーボードを閉じる方法を知りたい方

今回のソースコードは以下で公開されています。

https://github.com/kimuson/keyboard_close_demo

Flutter開発でキーボードを閉じる方法

キーボードを閉じる方法として、以下の3つがあります。

  1. キーボードの「done/完了」ボタンを押下する
  2. キーボードの外側をタップする
  3. キーボードを閉じるボタンを作って押下する

本記事でこれら3つの方法をご紹介していきます。

キーボードの「done/完了」ボタンを押下する

一番簡単な方法は、すでに標準実装されているキーボードの「done/完了」ボタンを押下してください。

主にテキスト入力する際に使用するwidgetはTextFieldまたはTextFormFieldになるかと思いますのでその際は以下のように操作いただければキーボードが閉じます。

キーボードの外側をタップする

キーボードの外側をタップしたら、キーボードを閉じるように実装できます。

こちらの処理を行う場合、以下のコードを使用します。

FocusScope.of(context).unfocus()

具体的には以下のようにGestureDetector()と組み合わせて使用します。

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(title: _title, home: MyStatefulWidget());
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        behavior: HitTestBehavior.opaque, //画面外タップを検知するために必要
        onTap: () => FocusScope.of(context).unfocus(),
        child: Center(
          child: TextField(),
        ),
      ),
    );
  }
}

重要なポイント

GestureDetector(
        behavior: HitTestBehavior.opaque, //画面外タップを検知するために必要
        onTap: () => FocusScope.of(context).unfocus(),
        child: Center(
          child: TextField(),
        ),
      )

GestureDetectorのonTapにFocusScope.of(context).unfocus()を実装します。

そして子ウィジェットにTextFieldやTextFormFieldなどのテキストフォーム系のwidgetを設定します。

そして忘れてはいけないのが「behavior: HitTestBehavior.opaque」の部分です。

今回のGestureDetectorは、すでに設置されたUI部品のタッチを検知します。

つまり、なにもUI部品が置かれていない場所にタッチをしても検知してくれず、キーボードを閉じる処理が発火しません。

今回はTextField()以外のUI部品を設置していないため、「behavior: HitTestBehavior.opaque」を設定しています。

キーボードを閉じるボタンを作って押下する

最後にご紹介するのは、キーボードを閉じるボタンを作って押下する方法です。

実際にこのアプローチを使用するシーンは少ないと思いますが、一応ご紹介します。

実装の考え方は画面外タップの時と同じです。

ボタンを押下したときに以下の処理が実行されるようにします。

FocusScope.of(context).unfocus()

以下のようにElevatedButton()を設置して、その中のonPressedに実装します。

ElevatedButton(
  onPressed: () {
    FocusScope.of(context).unfocus();
  },
  child: Text('Close'),
),

今回取り扱ったコードの全体像

以下のソースコードで画面外タップ&ボタン押下でキーボードを閉じることができます。

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(title: _title, home: MyStatefulWidget());
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        behavior: HitTestBehavior.opaque, //画面外タップを検知するために必要
        onTap: () => FocusScope.of(context).unfocus(),
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(),
              ElevatedButton(
                onPressed: () {
                  FocusScope.of(context).unfocus();
                },
                child: Text('Close'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

まとめ

今回はキーボードを閉じる処理について解説しました。

FocusScope.of(context).unfocus()をどのタイミング発火させるかがコツです!

今回のソースコードは以下で公開されています。

https://github.com/kimuson/keyboard_close_demo

最新のFlutterの勉強方法 まとめ

Flutterを入門から実践レベルまで一通り学習できる方法をまとめました。

Flutterの勉強方法を知る

Flutterを動画で学習する

Flutterを書籍で学習する