إنشاء أسلوب إدخال

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

لإضافة أداة IME إلى نظام Android، أنشئ تطبيق Android يحتوي على فئة توسّع InputMethodService. بالإضافة إلى ذلك، يمكنك عادةً إنشاء نشاط "الإعدادات" الذي يمرِّر الخيارات إلى خدمة IME. يمكنك أيضًا تحديد واجهة مستخدم للإعدادات يتم عرضها كجزء من إعدادات النظام.

تتناول هذه الصفحة المواضيع التالية:

إذا لم يسبق لك استخدام محرّرات طرق الإدخال، ننصحك بقراءة المقالة التمهيدية طرق الإدخال على الشاشة أولاً.

مراحل نشاط أداة IME

يوضّح الرسم البياني التالي دورة حياة أداة IME:

صورة تعرض دورة حياة محرر طريقة الإدخال (IME)
الشكل 1. دورة حياة طريقة الإدخال (IME)

توضّح الأقسام التالية كيفية تنفيذ واجهة المستخدم والرمز المرتبطين بأداة IME التي تتّبع دورة الحياة هذه.

تعريف مكوّنات طريقة الإدخال في ملف البيان

في نظام Android، تكون طريقة الإدخال عبارة عن تطبيق Android يحتوي على خدمة خاصة بطريقة الإدخال. يجب أن يصرّح ملف بيان التطبيق عن الخدمة، ويطلب الأذونات اللازمة، ويوفّر فلتر أهداف يتطابق مع الإجراء action.view.InputMethod، ويوفّر بيانات وصفية تحدّد خصائص طريقة الإدخال. بالإضافة إلى ذلك، لتوفير واجهة إعدادات تتيح للمستخدم تعديل سلوك أداة IME، يمكنك تحديد نشاط "الإعدادات" الذي يمكن تشغيله من "إعدادات النظام".

يعرض المقتطف التالي تعريفًا لخدمة IME. يطلب هذا الإذن BIND_INPUT_METHOD للسماح للخدمة بربط أداة IME بالنظام، ويضبط intent filter الذي يتطابق مع الإجراء android.view.InputMethod، ويحدّد البيانات الوصفية لأداة IME:

<!-- Declares the input method service. -->
<service android:name="FastInputIME"
    android:label="@string/fast_input_label"
    android:permission="android.permission.BIND_INPUT_METHOD">
    <intent-filter>
        <action android:name="android.view.InputMethod" />
    </intent-filter>
    <meta-data android:name="android.view.im"
               android:resource="@xml/method" />
</service>

يعرض المقتطف التالي نشاط الإعدادات الخاص بأداة IME. يحتوي على فلتر أهداف ACTION_MAIN يشير إلى أنّ هذا النشاط هو نقطة الدخول الرئيسية لتطبيق IME:

<!-- Optional: an activity for controlling the IME settings. -->
<activity android:name="FastInputIMESettings"
    android:label="@string/fast_input_settings">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
    </intent-filter>
</activity>

يمكنك أيضًا توفير إمكانية الوصول إلى إعدادات محرر أسلوب الإدخال مباشرةً من واجهة المستخدم.

واجهة برمجة التطبيقات الخاصة بطريقة الإدخال

يمكن العثور على الفئات الخاصة بطرق الإدخال في حزمتَي android.inputmethodservice و android.view.inputmethod. فئة KeyEvent مهمة للتعامل مع أحرف لوحة المفاتيح.

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

الفئات التالية مهمة أيضًا:

BaseInputConnection
تحدّد قناة الاتصال من InputMethod إلى التطبيق الذي يتلقّى مدخلاته. يمكنك استخدامها لقراءة النص حول المؤشر، وإرسال النص إلى مربع النص، وإرسال أحداث المفاتيح الأولية إلى التطبيق. يجب أن توسّع التطبيقات هذه الفئة بدلاً من تنفيذ الواجهة الأساسية InputConnection.
KeyboardView
هي امتداد View يعرض لوحة مفاتيح ويستجيب لأحداث بيانات أدخلها المستخدم. يتم تحديد تنسيق لوحة المفاتيح من خلال مثيل Keyboard، الذي يمكنك تحديده في ملف XML.

تصميم واجهة مستخدم أسلوب الإدخال

هناك عنصران مرئيان رئيسيان لطريقة الإدخال (IME): طريقة الإدخال والخيارات المقترَحة. عليك فقط تنفيذ العناصر ذات الصلة بطريقة الإدخال التي تصمّمها.

طريقة عرض الإدخال

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

Kotlin

override fun onCreateInputView(): View {
    return layoutInflater.inflate(R.layout.input, null).apply {
        if (this is MyKeyboardView) {
            setOnKeyboardActionListener(this@MyInputMethod)
            keyboard = latinKeyboard
        }
    }
}

Java

@Override
public View onCreateInputView() {
    MyKeyboardView inputView =
        (MyKeyboardView) getLayoutInflater().inflate(R.layout.input, null);

    inputView.setOnKeyboardActionListener(this);
    inputView.setKeyboard(latinKeyboard);

    return inputView;
}

في هذا المثال، MyKeyboardView هو مثيل لتنفيذ مخصّص من KeyboardView يعرض Keyboard.

طريقة عرض المرشّحين

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

اعتبارات تصميم واجهة المستخدم

يوضّح هذا القسم بعض الاعتبارات المتعلّقة بتصميم واجهة المستخدم لأدوات IME.

التعامل مع أحجام الشاشات المتعددة

يجب أن تكون واجهة المستخدم الخاصة بأداة IME قادرة على تغيير حجمها لتناسب أحجام الشاشات المختلفة والتعامل مع كل من الوضع الأفقي والاتجاه العمودي. في وضع أداة IME غير ملء الشاشة، يجب ترك مساحة كافية للتطبيق لعرض حقل النص وأي سياق مرتبط به، بحيث لا تشغل أداة IME أكثر من نصف الشاشة. لا تحدث هذه المشكلة في وضع ملء الشاشة لبرنامج IME.

التعامل مع أنواع الإدخال المختلفة

تتيح لك حقول النصوص في Android ضبط نوع إدخال معيّن، مثل نص حر وأرقام وعناوين URL وعناوين بريد إلكتروني وسلاسل بحث. عند تنفيذ طريقة إدخال جديدة، عليك رصد نوع الإدخال لكل حقل وتوفير الواجهة المناسبة له. ومع ذلك، ليس عليك إعداد أداة IME للتحقّق مما إذا كان المستخدم يدخل نصًا صالحًا لنوع الإدخال. وتقع مسؤولية ذلك على عاتق التطبيق الذي يملك حقل النص.

على سبيل المثال، إليك الواجهة التي توفّرها أداة IME اللاتينية لإدخال النص على نظام Android الأساسي:

صورة تعرض حقل إدخال نص على محرر أسلوب إدخال باللاتينية
الشكل 2. إدخال نصي باستخدام محرر أسلوب الإدخال (IME) للأحرف اللاتينية

في ما يلي الواجهة التي توفّرها أداة IME للّغات اللاتينية لإدخال الأرقام على نظام Android الأساسي:

صورة تعرض إدخالاً رقميًا على أداة IME لاتينية
الشكل 3. إدخال أرقام باستخدام أداة IME اللاتينية

عندما يركّز المستخدم على حقل إدخال ويبدأ تشغيل أداة IME، يستدعي النظام onStartInputView()، مع تمرير كائن EditorInfo يحتوي على تفاصيل حول نوع الإدخال وسمات أخرى لحقل النص. في هذا العنصر، يحتوي الحقل inputType على نوع الإدخال في حقل النص.

الحقل inputType هو int يحتوي على أنماط بت لإعدادات أنواع الإدخال المختلفة. لاختبار نوع الإدخال لحقل النص، يمكنك إخفاؤه باستخدام الثابت TYPE_MASK_CLASS، على النحو التالي:

Kotlin

inputType and InputType.TYPE_MASK_CLASS

Java

inputType & InputType.TYPE_MASK_CLASS

يمكن أن يحتوي نمط بت نوع الإدخال على إحدى القيم التالية:

TYPE_CLASS_NUMBER
حقل نصي لإدخال الأرقام كما هو موضّح في الشكل 3، تعرض أداة IME اللاتينية لوحة مفاتيح رقمية للحقول من هذا النوع.
TYPE_CLASS_DATETIME
حقل نص لإدخال التاريخ والوقت
TYPE_CLASS_PHONE
حقل نصي لإدخال أرقام الهواتف
TYPE_CLASS_TEXT
حقل نصي لإدخال أي أحرف متوافقة

يتم توضيح هذه الثوابت بمزيد من التفصيل في المستندات المرجعية الخاصة بـ InputType.

يمكن أن يحتوي الحقل inputType على أجزاء أخرى تشير إلى نوع مختلف من حقل النص، مثل:

TYPE_TEXT_VARIATION_PASSWORD
صيغة مختلفة من TYPE_CLASS_TEXT لإدخال كلمات المرور تعرض طريقة الإدخال رموزًا زخرفية بدلاً من النص الفعلي.
TYPE_TEXT_VARIATION_URI
شكل مختلف من TYPE_CLASS_TEXT لإدخال عناوين URL على الويب وغيرها من معرّفات الموارد المنتظمة (URI).
TYPE_TEXT_FLAG_AUTO_COMPLETE
صيغة من TYPE_CLASS_TEXT لإدخال نص يكمل التطبيق إدخاله تلقائيًا من قاموس أو بحث أو ميزة أخرى.

استبدِل inputType بالثابت المناسب عند اختبار هذه الصيغ. تتوفّر ثوابت القناع المتاحة في المستندات المرجعية الخاصة بـ InputType.

إرسال نص إلى التطبيق

عندما يُدخل المستخدم نصًا باستخدام أداة IME، يمكنك إرسال النص إلى التطبيق من خلال إرسال أحداث مفاتيح فردية أو تعديل النص حول المؤشر في حقل النص الخاص بالتطبيق. في كلتا الحالتين، استخدِم مثيلاً من InputConnection لعرض النص. للحصول على هذا الموضع، اتّصِل بـ InputMethodService.getCurrentInputConnection().

تعديل النص المحيط بالمؤشر

عند التعامل مع تعديل نص حالي، تتضمّن BaseInputConnection بعض الطرق المفيدة، وهي:

getTextBeforeCursor()
تعرض هذه السمة CharSequence التي تحتوي على عدد الأحرف المطلوبة قبل موضع المؤشر الحالي.
getTextAfterCursor()
تعرض هذه السمة CharSequence تحتوي على عدد الأحرف المطلوبة بعد موضع المؤشر الحالي.
deleteSurroundingText()
يحذف هذا الإجراء عدد الأحرف المحدّد قبل موضع المؤشر الحالي وبعده.
commitText()
تُضيف CharSequence إلى حقل النص وتضبط موضعًا جديدًا للمؤشر.

على سبيل المثال، يعرض المقتطف التالي كيفية استبدال الأحرف الأربعة على يسار المؤشر بالنص "Hello!‎":

Kotlin

currentInputConnection.also { ic: InputConnection ->
    ic.deleteSurroundingText(4, 0)
    ic.commitText("Hello", 1)
    ic.commitText("!", 1)
}

Java

InputConnection ic = getCurrentInputConnection();
ic.deleteSurroundingText(4, 0);
ic.commitText("Hello", 1);
ic.commitText("!", 1);

إتاحة كتابة النص قبل إرساله

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

يوضّح المقتطف التالي كيفية عرض مستوى التقدّم في حقل نصي:

Kotlin

currentInputConnection.also { ic: InputConnection ->
    ic.setComposingText("Composi", 1)
    ic.setComposingText("Composin", 1)
    ic.commitText("Composing ", 1)
}

Java

InputConnection ic = getCurrentInputConnection();
ic.setComposingText("Composi", 1);
ic.setComposingText("Composin", 1);
ic.commitText("Composing ", 1);

اعتراض أحداث مفاتيح الأجهزة

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

لاعتراض مفاتيح الأجهزة، عليك إلغاء onKeyDown() و onKeyUp().

استدعِ طريقة super() للمفاتيح التي لا تريد التعامل معها بنفسك.

إنشاء نوع فرعي من طريقة الإدخال

تتيح الأنواع الفرعية لطريقة الإدخال (IME) عرض أوضاع إدخال ولغات متعددة متوافقة مع طريقة الإدخال (IME). يمكن أن يمثّل النوع الفرعي ما يلي:

  • لغة، مثل en_US أو fr_FR
  • وضع إدخال، مثل الصوت أو لوحة المفاتيح أو الكتابة اليدوية
  • أنماط الإدخال أو النماذج أو الخصائص الأخرى الخاصة بطريقة الإدخال، مثل تنسيقات لوحة المفاتيح ذات العشرة مفاتيح أو QWERTY

يمكن أن يكون الوضع أي نص، مثل "لوحة المفاتيح" أو "الصوت". يمكن أن يعرض النوع الفرعي أيضًا مزيجًا من هذه الأنواع.

تُستخدَم معلومات النوع الفرعي لمربّع حوار مبدّل IME المتوفّر من شريط الإشعارات ولإعدادات IME. تتيح المعلومات أيضًا للإطار عرض نوع فرعي معيّن من محرر طريقة الإدخال مباشرةً. عند إنشاء أداة IME، استخدِم ميزة النوع الفرعي لأنّها تساعد المستخدم في تحديد لغات وأوضاع IME المختلفة والتبديل بينها.

حدِّد الأنواع الفرعية في أحد ملفات موارد XML الخاصة بطريقة الإدخال، وذلك باستخدام العنصر <subtype>. يحدّد مقتطف الرمز التالي أداة IME بنوعَين فرعيَين: نوع فرعي للوحة المفاتيح خاص باللغة الإنجليزية في الولايات المتحدة، ونوع فرعي آخر للوحة المفاتيح خاص باللغة الفرنسية في فرنسا:

<input-method xmlns:android="http://schemas.android.com/apk/res/android"
        android:settingsActivity="com.example.softkeyboard.Settings"
        android:icon="@drawable/ime_icon">
    <subtype android:name="@string/display_name_english_keyboard_ime"
            android:icon="@drawable/subtype_icon_english_keyboard_ime"
            android:languageTag="en-US"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="somePrivateOption=true" />
    <subtype android:name="@string/display_name_french_keyboard_ime"
            android:icon="@drawable/subtype_icon_french_keyboard_ime"
            android:languageTag="fr-FR"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="someVariable=30,someInternalOption=false" />
    <subtype android:name="@string/display_name_german_keyboard_ime" ... />
</input-method>

للتأكّد من تصنيف الأنواع الفرعية بشكل صحيح في واجهة المستخدم، استخدِم `%s` للحصول على تصنيف نوع فرعي مطابق لتصنيف اللغة الخاص بالنوع الفرعي. يتم توضيح ذلك في مقتطفي الرمز البرمجي التاليين. يعرض المقتطف الأول جزءًا من ملف XML الخاص بطريقة الإدخال:

<subtype
    android:label="@string/label_subtype_generic"
    android:imeSubtypeLocale="en_US"
    android:icon="@drawable/icon_en_us"
    android:imeSubtypeMode="keyboard" />

المقتطف التالي هو جزء من ملف strings.xml الخاص بمحرِّر طريقة الإدخال. يتم تعريف مورد السلسلة label_subtype_generic، الذي تستخدمه تعريف واجهة مستخدم طريقة الإدخال لضبط تصنيف النوع الفرعي، على النحو التالي:

<string name="label_subtype_generic">%s</string>

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

اختيار أنواع فرعية لطريقة الإدخال (IME) من شريط الإشعارات

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

صورة تعرض قائمة &quot;النظام&quot; في &quot;اللغات والإدخال&quot;
الشكل 4. قائمة النظام اللغات والإدخال

اختيار أنواع محرّك IME الفرعية من "إعدادات النظام"

يمكن للمستخدم أيضًا التحكّم في كيفية استخدام الأنواع الفرعية في لوحة إعدادات اللغة والإدخال ضمن إعدادات النظام:

صورة تعرض قائمة اختيار اللغات
الشكل 5. قائمة النظام اللغات

التبديل بين الأنواع الفرعية لأداة IME

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

  1. عليك تعريف supportsSwitchingToNextInputMethod = "true" في ملفات موارد XML الخاصة بطريقة الإدخال. يجب أن يبدو بيانك مشابهًا لمقتطف الرمز التالي:
    <input-method xmlns:android="http://schemas.android.com/apk/res/android"
            android:settingsActivity="com.example.softkeyboard.Settings"
            android:icon="@drawable/ime_icon"
            android:supportsSwitchingToNextInputMethod="true">
  2. استدعِ طريقة shouldOfferSwitchingToNextInputMethod().
  3. إذا عرضت الطريقة القيمة "صحيح"، اعرض مفتاح تبديل.
  4. عندما ينقر المستخدم على مفتاح التبديل، يتم استدعاء الدالة switchToNextInputMethod() مع تمرير القيمة false. تشير القيمة false إلى أنّ النظام سيتعامل مع جميع الأنواع الفرعية بشكل متساوٍ، بغض النظر عن IME الذي تنتمي إليه. يؤدي تحديد القيمة "صحيح" إلى مطالبة النظام بالتنقل بين الأنواع الفرعية في أداة IME الحالية.

اعتبارات عامة بشأن أداة IME

في ما يلي بعض الأمور الأخرى التي يجب مراعاتها أثناء تنفيذ أداة IME:

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