GameTextInput   بخشی از کیت توسعه بازی Android.

استفاده از کتابخانه GameTextInput جایگزین ساده‌تری برای نوشتن برنامه Android تمام‌صفحه است که از صفحه‌کلید نرم برای ورودی نوشتار استفاده می‌کند.

GameTextInput میانای برنامه‌سازی کاربردی ساده‌ای برای نمایش یا پنهان کردن صفحه‌کلید نرم، تنظیم یا دریافت نوشتار درحال ویرایش، و دریافت اعلان هنگام تغییر نوشتار ارائه می‌دهد. این ویژگی برای برنامه‌های ویرایشگر نوشتار کامل درنظر گرفته نشده است، اما همچنان از انتخاب و ترکیب منطقه برای موارد استفاده معمول در بازی‌ها پشتیبانی می‌کند. همچنین، این کتابخانه از ویژگی‌های پیشرفته ویرایشگر روش ورودی (IME) مانند بررسی املا، تکمیل، و نویسه‌های چندکلیدی پشتیبانی می‌کند.

در داخل، GameTextInput نوشتار ورودی (همراه با وضعیت‌های مربوطه) را در بافر داخلی GameTextInput::currentState_ جمع‌آوری می‌کند و برنامه را از هرگونه تغییر در آن مطلع می‌کند. سپس برنامه پردازش نوشتار را در تابع بازخوانی ثبت‌شده خود انجام می‌دهد.

دردسترس بودن

می‌توانید از GameTextInput به روش‌های زیر استفاده کنید:

  • همراه با GameActivity: GameActivity،‏ GameTextInput را ادغام می‌کند. برنامه‌هایی که از GameActivity استفاده می‌کنند فقط می‌توانند از GameTextInput یکپارچه استفاده کنند. دستورالعمل‌های استفاده به‌طور کامل در صفحه GameActivity مستند شده است. برای نمونه‌ای از ادغام GameActivity و GameTextInput، به مخزن games-samples مراجعه کنید. این مدل استفاده در محدوده این راهنما نیست.

  • به‌عنوان کتابخانه مستقل: بقیه راهنما مراحل استفاده را شرح می‌دهد.

توجه داشته باشید که دو روش بالا متقابلاً انحصاری هستند.

نسخه‌های رسمی GameTextInput در کتابخانه بازی‌های Jetpack در Google Maven دردسترس است.

راه‌اندازی ساختار

‫GameTextInput به‌عنوان بایگانی Android (AAR) توزیع می‌شود. این AAR حاوی کلاس‌های Java و کد منبع C است که ویژگی‌های بومی GameTextInput را پیاده‌سازی می‌کند. باید این فایل‌های منبع را به‌عنوان بخشی از فرایند ساخت ازطریق Prefab اضافه کنید، که کتابخانه‌های بومی و کد منبع را در پروژه CMake یا ساخت NDK شما نمایان می‌کند.

  1. برای افزودن وابستگی کتابخانه GameTextInput به فایل build.gradle بازی‌تان، دستورالعمل‌های صفحه بازی‌های Android با Jetpack را دنبال کنید. توجه داشته باشید که اگر برنامه‌هایتان از 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 فایل در بازی‌تان، خط زیر را اضافه کنید تا پیاده‌سازی 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. از رشته C که ازقبل به JVM پیوست شده است، یا رشته اصلی برنامه، با یک اشاره‌گر 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. یک کلاس InputEnabledTextView جاوا با دسترسی به InputConnection ایجاد کن.

    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 ساخته‌شده را به چیدمان واسط کاربر اضافه کنید. برای مثال، کد زیر در 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 خود بازیابی کنید. وقتی از View Binding استفاده می‌کنید، این کار نسبتاً ساده است:

    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 خود، inputConnection را به GameTextInput_setInputConnection ارسال کنید. برای اینکه از رویدادها به‌عنوان ساختار حالت C GameTextInputState مطلع شوید، GameTextInput_setEventCallback یک تماس برگشتی ارسال کنید.

    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 شامل توابع کمکی است که به شما امکان می‌دهد بین ساختارهای وضعیت C و اشیای وضعیت جاوا تبدیل کنید. ازطریق توابع GameTextInput_showIme و GameTextInput_hideIme به عملکرد نمایش دادن و پنهان کردن IME دسترسی پیدا کنید.

مرجع‌ها

توسعه‌دهندگان ممکن است موارد زیر را هنگام ایجاد برنامه‌های GameTextInput مفید بدانند:

بازخورد

برای هرگونه مشکل و سؤال درباره GameTextInput، گزارش اشکالی در Google IssueTracker ایجاد کنید.