GameTextInput جزء من حزمة تطوير ألعاب Android.

يُعد استخدام مكتبة GameTextInput بديلاً أبسط لكتابة تطبيق Android بملء الشاشة يستخدم لوحة المفاتيح اللينة لإدخال النص.

GameTextInput توفّر واجهة برمجة تطبيقات واضحة لإظهار لوحة المفاتيح اللينة أو إخفائها، وضبط النص المعدَّل أو الحصول عليه، وتلقّي إشعارات عند تغيير النص. لا ينطبق هذا على تطبيقات محرر النصوص الكاملة، ولكنه لا يزال يوفر إمكانية الاختيار وتكوين المنطقة لحالات الاستخدام النموذجية في الألعاب. وتوفّر هذه المكتبة أيضًا ميزات متقدّمة لمحرر أسلوب الإدخال (IME)، مثل التدقيق الإملائي والإكمالات والأحرف المتعددة المفاتيح.

داخليًا، تجمع GameTextInput نص الإدخال (مع الحالات ذات الصلة) في المخزن المؤقت الداخلي GameTextInput::currentState_ وتُبلِغ التطبيق بأي تغييرات فيه. يُجري التطبيق بعد ذلك معالجة النص في دالة معاودة الاتصال المسجلة.

أماكن التوفّر

يمكن استخدام GameTextInput بالطرق التالية:

  • مع GameActivity: تدمج GameActivity GameTextInput. ويمكن للتطبيقات التي تستخدم GameActivity استخدام GameTextInput المُدمج فقط. تم توثيق تعليمات الاستخدام بالكامل على صفحة GameActivity . للحصول على عيّنة من عملية دمج GameActivity وGameTextInput، يمكنك الاطّلاع على مستودع نماذج الألعاب. ونموذج الاستخدام هذا ليس ضمن نطاق هذا الدليل.

  • باعتباره مكتبة مستقلة: يصف باقي الدليل خطوات الاستخدام.

تجدر الإشارة إلى أن الطريقتين السابقتين متنافيتان.

تتوفّر إصدارات GameTextInput الرسمية في القنوات التالية:

يتناول هذا الدليل حالة الاستخدام الأولى. لاستخدام إصدارات الملف المضغوط، راجع التعليمات التي تم شحنها داخل الحزمة.

إعداد إصدارك

يتم توزيع GameTextInput في شكل أرشيف Android (AAR). يحتوي AAR هذا على فئات Java ورمز المصدر C الذي ينفِّذ الميزات الأصلية لـ GameTextInput. عليك تضمين ملفات المصدر هذه كجزء من عملية الإنشاء من خلال Prefab، التي تعرض المكتبات الأصلية ورمز المصدر لمشروع CMake أو إصدار NDK.

  1. اتّبِع التعليمات الواردة في صفحة ألعاب Jetpack على أجهزة Android لإضافة إضافة مكتبة "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 في لعبتك، أضِف السطر التالي لتضمين عملية تنفيذ GameTextInput:

    #include <game-text-input/gametextinput.cpp>
    
  5. في ملفات المصدر التي تستخدم واجهة برمجة التطبيقات GameTextInput C، ضمِّن ملف العنوان:

    #include <game-text-input/gametextinput.h>
    
  6. جمِّع التطبيق وشغّله. وإذا ظهرت لك أخطاء CMake، تحقَّق من إعداد AAR وملفات build.gradle بشكل صحيح. إذا لم يتم العثور على ملف #include، تحقَّق من ملف الإعداد CMakeLists.txt.

دمج تصميمك

  1. من سلسلة محادثات C التابعة لك المرتبطة حاليًا بأداة JVM أو سلسلة التعليمات الرئيسية للتطبيق، استدعِ GameTextInput_init باستخدام مؤشر JNIEnv.

    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. يمكنك إنشاء فئة Java 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. يعتبر هذا أمرًا بسيطًا نسبيًا عند استخدام ربط طرق العرض:

    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. مرِّر معاودة الاتصال في 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. يمكنك الوصول إلى وظيفة عرض أداة IME وإخفائها من خلال دالتي GameTextInput_showIme وGameTextInput_hideIme.

المراجع

قد يستفيد مطوّرو التطبيقات مما يلي عند إنشاء تطبيقات باستخدام GameTextInput:

ملاحظات

إذا كانت لديك أي مشاكل أو أسئلة متعلّقة بـ GameTextInput، يمكنك إنشاء خطأ في أداة تتبّع المشاكل من Google.