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

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

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

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

إذا لم يسبق لك استخدام برامج IME، يُرجى قراءة المقالة التمهيدية طرق الإدخال على الشاشة أولاً.

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

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

صورة تعرض دورة حياة محرِّر أسلوب الإدخال
الشكل 1: مراحل نشاط محرِّر أسلوب الإدخال

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

تعريف مكوّنات IME في البيان

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

يعرّف المقتطف التالي خدمة 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. يحتوي على intent filter لـ 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>

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

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

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

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

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

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

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

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

عرض الإدخال

طريقة عرض الإدخال هي واجهة المستخدم التي يُدخل فيها المستخدم النص على شكل نقرات على المفاتيح أو كتابة بخط اليد أو إيماءات. عند عرض أداة 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 اللاتينية لإدخال النص في نظام Android الأساسي:

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

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

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

عندما يتم التركيز على حقل إدخال ويبدأ محرِّر أسلوب الإدخال، يستدعي النظام 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 في حقل النص وضبط موضع جديد للمؤشر.

على سبيل المثال، يوضّح المقتطف التالي كيفية استبدال الأحرف الأربعة الموجودة على يمين المؤشر بالنص "مرحبًا":

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);

إتاحة إنشاء النص قبل تنفيذه

إذا كان محرّر أسلوب الإدخال يتوقّع النص أو يتطلّب خطوات متعدّدة لإنشاء رمز أو كلمة، يمكنك عرض مستوى التقدّم في حقل النص إلى أن يثبّت المستخدم الكلمة، وبعد ذلك يمكنك استبدال التركيب الجزئي بالنص المكتمل. يمكنك منح النص معاملة خاصة من خلال إضافة 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

تتيح الأنواع الفرعية لمحرِّر أسلوب الإدخال عرض أوضاع إدخال ولغات متعددة متوافقة مع محرِّر أسلوب الإدخال. يمكن أن يمثل النوع الفرعي ما يلي:

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

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

تُستخدم معلومات النوع الفرعي لمربّع حوار مبدّل أسلوب الإدخال المتاح من شريط الإشعارات ولإعدادات أسلوب الإدخال. تتيح هذه المعلومات أيضًا لإطار العمل عرض نوع فرعي معيّن من "محرِّر أسلوب الإدخال" مباشرةً. عند إنشاء أداة 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>

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

اختيار الأنواع الفرعية لأساليب الإدخال من شريط الإشعارات

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

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

اختيار الأنواع الفرعية لأساليب الإدخال من "إعدادات النظام"

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

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

التبديل بين الأنواع الفرعية لأساليب الإدخال

يمكنك السماح للمستخدمين بالتبديل بسهولة بين الأنواع الفرعية لأداة 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 العديد من الأحرف المختلفة للسماح للمستخدمين بإدخال كلمة مرور والوصول إلى الأجهزة.