GameTextInput   Android Game Development Kit の一部。

GameTextInput ライブラリを使用すると、ソフト キーボードのテキスト入力を使用する全画面 Android アプリをさらに簡単に作成できます。

GameTextInput は、ソフト キーボードの表示と非表示を切り替えたり、現在編集されているテキストの設定と取得をしたり、テキストが変更されたときに通知を受け取ったりする、シンプルな API を提供します。これは、本格的なテキスト エディタ アプリ向けではありませんが、ゲームの一般的なユースケース向けの選択と作成領域に対応しています。また、このライブラリは、スペルチェック、補完、マルチキー文字などの高度なインプット メソッド エディタ(IME)機能にも対応しています。

内部的には、GameTextInput は入力テキストを(関連する状態とともに)内部バッファ GameTextInput::currentState_ に蓄積し、その変化をアプリに通知します。アプリは登録されたコールバック関数でテキスト処理を行います。

提供状況

GameTextInput は次のように使用できます。

  • GameActivity と連携: GameActivity は GameTextInput を統合します。GameActivity を使用するアプリは、統合された GameTextInput のみ使用できます。使用手順について詳しくは、GameActivity のページをご覧ください。GameActivity と GameTextInput の統合のサンプルについては、games-samples リポジトリをご覧ください。この使用モデルはこのガイドの対象外です。

  • スタンドアロン ライブラリとしての使用: 以降のセクションでこの使用手順について説明します。

なお、この 2 つの方法は相互に排他的です。

正式な GameTextInput リリースは次のチャンネルで利用可能です。

このガイドでは、最初の使用ケースを説明します。ZIP ファイル リリースを使用する場合は、パッケージ内の手順を参照してください。

ビルドをセットアップする

GameTextInputAndroid ARchive(AAR)として配布されます。この AAR には、GameTextInput のネイティブ機能を実装する Java クラスと C のソースコードが含まれています。Prefab を介して、これらのソースファイルをビルドプロセスの一部として組み込む必要があります。Prefab は、ネイティブ ライブラリとソースコードを CMake プロジェクトまたは NDK ビルドに公開します。

  1. Jetpack Android Games のページに記載されている手順に沿って、GameTextInput ライブラリの依存関係をゲームの build.gradle ファイルに追加します。なお、アプリが GameActivity を使用している場合、スタンドアロンの GameTextInput ライブラリは使用できません

  2. gradle.properties に以下の行が含まれていることを確認します。

    # Tell Android Studio we are using AndroidX.
    android.useAndroidX=true
    # Use Prefab 1.1.2 or higher, which contains a fix for "header only" libs.
    android.prefabVersion=1.1.2
    # Required only if you're using Android Studio 4.0 (4.1 is recommended).
    # android.enablePrefab=true
    
  3. game-text-input パッケージをインポートしてプロジェクトの CMakeLists.txt ファイル内のターゲットに追加します。

    find_package(game-text-input REQUIRED CONFIG)
    ...
    target_link_libraries(... game-text-input::game-text-input)
    
  4. ゲームの .cpp ファイルの 1 つに次の行を追加して、GameTextInput 実装を組み込みます。

    #include <game-text-input/gametextinput.cpp>
    
  5. GameTextInput C API を使用しているソースファイルには、ヘッダー ファイルを組み込みます。

    #include <game-text-input/gametextinput.h>
    
  6. アプリをコンパイルして実行します。CMake エラーが発生した場合は、AAR と build.gradle ファイルが適切にセットアップされているかどうかを確認します。#include ファイルが見つからない場合は、CMakeLists.txt 構成ファイルを確認してください。

ビルドを統合する

  1. JVM にアタッチ済みの C スレッド、またはアプリのメインスレッドから、JNIEnv ポインタで GameTextInput_init を呼び出します。

    static GameTextInput* gameTextInput = nullptr;
    
    extern "C"
    JNIEXPORT void JNICALL
    Java_com_gametextinput_testbed_MainActivity_onCreated(JNIEnv* env,
      jobject this) {
    {
        if(!gameTextInput)
          gameTextInput = GameTextInput_init(env);
        ...
    }
    
  2. InputConnection にアクセスできる InputEnabledTextView Java クラスを作成します。

    public class InputEnabledTextView extends View implements Listener {
      public InputConnection mInputConnection;
      public InputEnabledTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
      }
    
      public InputEnabledTextView(Context context) {
        super(context);
      }
      public void createInputConnection(int inputType) {
        EditorInfo editorInfo = new EditorInfo();
        editorInfo.inputType = inputType;
        editorInfo.actionId = IME_ACTION_NONE;
        editorInfo.imeOptions = IME_FLAG_NO_FULLSCREEN;
        mInputConnection = new InputConnection(this.getContext(), this,
                new Settings(editorInfo, true)
        ).setListener(this);
      }
    
      @Override
      public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        if (outAttrs != null) {
            GameTextInput.copyEditorInfo(mInputConnection.getEditorInfo(), outAttrs);
        }
        return mInputConnection;
      }
    
      // Called when the IME input changes.
      @Override
      public void stateChanged(State newState, boolean dismissed) {
        onTextInputEventNative(newState);
      }
      @Override
      public void onImeInsetsChanged(Insets insets) {
        // handle Inset changes here
      }
    
      private native void onTextInputEventNative(State softKeyboardEvent);
    }
    
  3. 作成した InputEnabledTextView を UI レイアウトに追加します。たとえば、activity_main.xml の次のコードは、画面下部に配置できます。

    <com.android.example.gametextinputjava.InputEnabledTextView
        android:id="@+id/input_enabled_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
    
  4. この新しい InputEnabledTextView クラスを Java アクティビティに取得します。ビュー バインディングを使用すると比較的簡単です。

    public class MainActivity extends AppCompatActivity {
      ...
      private ActivityMainBinding binding;
      private InputEnabledTextView inputEnabledTextView;
    
      private native void setInputConnectionNative(InputConnection c);
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        ...
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        inputEnabledTextView = binding.inputEnabledTextView;
        inputEnabledTextView.createInputConnection(InputType.TYPE_CLASS_TEXT);
        setInputConnectionNative(inputEnabledTextView.mInputConnection);
      }
    
  5. C ライブラリで、inputConnectionGameTextInput_setInputConnection に渡します。コールバックを GameTextInput_setEventCallback で渡し、C の状態構造体 GameTextInputState としてイベントが通知されるようにします。

    extern "C"JNIEXPORT void JNICALL
    Java_com_gametextinput_testbed_MainActivity_setInputConnectionNative(
      JNIEnv *env, jobject this, jobject inputConnection) {
      GameTextInput_setInputConnection(gameTextInput, inputConnection);
      GameTextInput_setEventCallback(gameTextInput,[](void *ctx, const GameTexgtInputState *state) {
        if (!env || !state) return;
        // process the newly arrived text input from user.
        __android_log_print(ANDROID_LOG_INFO, "TheGreateGameTextInput", state->text_UTF8);
      }, env);
    }
    
  6. C ライブラリでは、状態が変化したときにアプリがイベントを処理するため、前の手順で登録したコールバックを内部的に呼び出す GameTextInput_processEvent を呼び出します。

    extern "C"
    JNIEXPORT void JNICALL
    Java_com_gametextinput_testbed_InputEnabledTextView_onTextInputEventNative(
      JNIEnv* env, jobject this, jobject soft_keyboard_event) {
      GameTextInput_processEvent(gameTextInput, soft_keyboard_event);
    }
    

ユーティリティ関数

GameTextInput ライブラリには、Java の状態オブジェクトと C の状態構造体の間で変換を行うユーティリティ関数が含まれています。GameTextInput_showIme 関数と GameTextInput_hideIme 関数を使用すると、IME の表示と非表示を切り替えられます。

参照

GameTextInput でアプリを作成する際、以下の情報を参考にしてください。

フィードバック

GameTextInput に関して問題を発見した場合や質問がある場合には、Google Issue Tracker でバグを登録してください。