FlutterとSEO、ときどき仕事

Dart, flutter, アプリ開発日記

【アプリ開発日記】キーボードのイベントを通知する【part4】

本記事はFlutterを使ったWordleクローンアプリ開発日記のpart4になります

以前の記事:

【アプリ開発日記】アプリを開発するにあたっての流れとコツ【part1】

【アプリ開発日記】Widgetを切り出して作成する【part2】

【アプリ開発日記】ブロックのWidgetを作成する【part3】

キーボードのイベントをmain.dartまで通知する

part2で作成したキーボードWidgetから通知するために、SoftwareKeyBoartクラスとKeyButtonクラスのコンストラクタをコールバック関数を引数に持つように修正します。

以下は修正箇所を抜粋したコードです。GestureDetectorからコールバックを受けたonTapを通じて、さらに親のWidgetへ通知するようなイメージです。今回は追加した関数(Functionで定義しているもの)をnon-nullとしているためそのまま呼び出していますが、null 許容する場合はnullチェックが必要になるので注意しましょう。

class SoftwareKeyBoard extends StatelessWidget {
  const SoftwareKeyBoard({
    Key? key,
    required this.onTapKey,
    required this.onTapEnterKey,
    required this.onTapDeleteKey
  }) : super(key: key);

  // コールバック用関数を追加。親Widgetで条件文を追加しなくて済むよう、
  // EnterとDeleteキー用のコールバック関数を定義している
  final Function(String) onTapKey;
  final Function() onTapEnterKey;
  final Function() onTapDeleteKey;

  @override
  Widget build(BuildContext context) {
    // 中略
  }

  /// 文字一覧からKeyButtonのリストを生成する
  List<KeyButton> createLine(List<String> list) {
    List<KeyButton> buttonList = [];
    for (String char in list) {
      // KeyButtonのonTapが呼ばれると、さらに親のWidgetへ通知できるよう、それぞれ追加したコールバック関数を呼び出す
      buttonList.add(KeyButton(char: char, onTap: () {
        if (char == 'ENTER') {
          onTapEnterKey();
        } else if (char == 'DEL') {
          onTapDeleteKey();
        } else {
          onTapKey(char);
        }
      }));
    }
    return buttonList;
  }
}

class KeyButton extends StatelessWidget {
  final String char;
  const KeyButton({
    Key? key,
    required this.char,
    required this.onTap
  }) : super(key: key);

  final Function() onTap; // コールバック用関数追加

  @override
  Widget build(BuildContext context) {
    // 中略
    return GestureDetector(
      onTap: () {
        onTap(); // GestureDetectorのonTapをそのまま通知する
      },
      child: Container(
        margin: const EdgeInsets.all(4),
        decoration: BoxDecoration(
          color: Colors.grey[350],
          borderRadius: BorderRadius.circular(3),
        ),
        width: width.toDouble(),
        height: 45,
        alignment: Alignment.center,
        child: w,
      ),
    );
  }
}

最後に、main.dart側のScaffold内でインスタンスを生成する時にコールバック用の処理を追記します。これで、キーボードのボタンを押すと、main.dart(の中のScaffold)へ通知することができました。

SoftwareKeyBoard(
  onTapEnterKey: () {
    debugPrint('onTapEnterKey');
  },
  onTapKey: (String char) {
    debugPrint('onTap : $char');
  },
  onTapDeleteKey: () {
    debugPrint('onTapDeleteKey');
   },
),

part5へ続く

コメントを残す