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

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

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

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

مدى التوفّر

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

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

  • كمكتبة مستقلة: توضّح بقية أقسام الدليل خطوات الاستخدام.

يُرجى العِلم أنّ الطريقتَين أعلاه تستبعدان بعضهما.

تتوفّر إصدارات GameTextInput الرسمية في مكتبة ألعاب Jetpack الإصدار في [Google Maven][google-maven]{:.external}.

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

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

  1. اتّبِع التعليمات الواردة في صفحة ألعاب Android من Jetpack لإضافة تبعية مكتبة 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 التي سبق أن تم إرفاقها بآلة Java الافتراضية (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. أنشئ فئة InputEnabledTextView Java تتيح الوصول إلى 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.