📚

【Flutter】英英辞書と日英辞書を同じTextFieldで実現する

2024/09/17に公開

私の作っているアプリ、実は同じTextFieldに英語を入れても日本語を入れても英単語を検索できます。それどころか母国語設定しておけば韓国語でも中国語でもスウェーデン語でもフランス語でも英単語を検索できます。

英英 日英

英英とか日英とか切り替えなくても、勝手にアプリが言語を認識して翻訳するのか似た単語を出すのか判別しているのです。

以下の3ステップで、実現しています。

  • ①TextFieldのonChangedで言語を認識
  • ②TextFieldのonChangedが走るたびに(日本語だったら)タイマーをリセット
  • ③Geminiで翻訳候補を出してもらう

①TextFieldのonChangedで言語を認識

わかりやすく省略していますが、TextFieldのonChangedは以下のようになっています。

    TextField(
      onChanged: (String text) async {
        final bool isYourLanguage =
            await _onDeviceTranslateRepository.checkIsYourLanguage(text);

        if (isYourLanguage) {
      // 英語以外の言語が来たら、いわゆる日英辞書
          _resetTimer();
        } else {
          // いわゆる英英辞書
          _getSuggestions(text);
        }
      },
    )

まず、isYourLanguage の決定ロジックですが、google_mlkit_language_idを使っています。ここでは、生成AIではなく昔からあるMLKitの言語認識機能で、何語なのかチェックします。(アルファベットを使っている単語は自動判別がむずいので母国語設定している言語なのかどうか判別しています。)

https://pub.dev/packages/google_mlkit_language_id

②TextFieldのonChangedが走るたびに(日本語だったら)タイマーをリセット

で、タイマーを回します。

  void _resetTimer() {
    _checkTypingTimer?.cancel();
    _startCheckTypingTimer();
  }

  Future _startCheckTypingTimer() async {
    _checkTypingTimer = Timer(const Duration(milliseconds: 1000), () async {
      setState(() {
        _suggestions = [translatingText];
      });

      final text = _controller.text;

      // ここで生成AI
      await _getTranslatedSuggestions(text);
    });
  }

タイマーを回している理由は、単語の入力が完了するのを待つためです。「りんご」と打つときに、「」だけの段階で生成AI投げたらAPIの回数が勿体無いないので、入力が終わってから1秒は次の文字が来るかもしれないので検索しないようにしています。

日本語が続く限りはonChangedで _resetTimer が呼ばれるので、ユーザーの一文字の入力が1秒より早ければ、入力完了まで検索を待てるというわけです。

途中で日本語をやめた場合も1回だけはAPI呼んでしまいますが、そこはご愛嬌です。

③Geminiで翻訳候補を出してもらう

で、最終的には以下のようなプロンプトで、Geminiに検索させています。

  Future<String> showPossibleTranslations(String yourMotherLanguageWord) async {
    final prompt = '''
    Please provide multiple possible translations of the word “$yourMotherLanguageWord” into English, separated by commas, without any spaces after the commas.
    For example, if the word you want to look up is “めんどくさい” in Japanese, the output should be as follows.
    「tedious,bothersome,tiresome,annoying」
    ''';
    return await _generateContent(prompt) ??
        'No response because Gemini API went wrong.';
  }

“$yourMotherLanguageWord” into English みたい感じで何語が来ても変数として打ち込んで雑に投げれるのが、生成AIのアツイところです。

ちなみに英英辞書の方は生成AIではなくDatamuseというフリーのAPIを使っています。

以上です。

アプリダウンロードはこちら

英語学習してる方は単語帳としてよかったら使ってください!

https://apps.apple.com/jp/app/id6480291526

https://play.google.com/store/apps/details?id=jp.kboy.tango&hl=en

投票してね

9月30日まで、ユーザー投票期間となっているので、ぜひ以下からこのアプリに投票お願いします!

https://ai.google.dev/competition/projects/ai-powered-english-wordbook

Flutter大学

Discussion