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

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

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

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

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

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

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

  • كمكتبة مستقلة: يصف الجزء المتبقي من الدليل خطوات الاستخدام.

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

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

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

إعداد الإصدار

يتم توزيع GameTextInput باعتباره أرشيف Android (AAR). يحتوي AAR هذا على فئات Java ورمز المصدر C الذي ينفّذ الميزات الأصلية لـ GameTextInput. عليك تضمين ملفات المصدر هذه كجزء من عملية التصميم من خلال 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 في لعبتك، أضِف السطر التالي لتضمين عملية تنفيذ 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 أو سلسلة التعليمات الرئيسية للتطبيق، استدعِ 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.