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

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

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

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

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

مراحل نشاط IME

يصف الرسم البياني التالي دورة حياة واجهة برمجة التطبيقات لمعالجة المعلومات.

صورة تعرض دورة حياة واجهة برمجة التطبيقات لمعالجة النصوص
الشكل 1. دورة حياة واجهة برمجة التطبيقات لمعالجة النصوص

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

الإفصاح عن مكوّنات IME في البيان

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

يعلن المقتطف التالي عن خدمة IME. يطلب الإذن BIND_INPUT_METHOD للسماح للخدمة بربط IME بالنظام، ويُعدّل فلتر الغرض الذي يتطابق مع الإجراء 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>

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

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

يمكن العثور على الصفوف الخاصة بخدمات IME في الحِزم android.inputmethodservice و android.view.inputmethod. صف KeyEvent مهم لمعالجة أحرف لوحة المفاتيح.

الجزء المركزي من واجهة ترجمة المحادثات هو مكوّن الخدمة، وهو فئة تمتد من 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 بملء الشاشة.

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

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

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

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

في ما يلي الواجهة التي يوفّرها معالج الكتابة اللاتيني لنظام التشغيل Android لإدخال الأرقام:

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

عندما يتلقّى حقل إدخال التركيز ويبدأ 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، يعرض أسلوب إدخال النص اللاتيني keypad للأحياء من هذا النوع.
TYPE_CLASS_DATETIME
حقل نص لإدخال التاريخ والوقت
TYPE_CLASS_PHONE
حقل نصي لإدخال أرقام الهواتف
TYPE_CLASS_TEXT
حقل نصي لإدخال أي أحرف مسموح بها

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

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

TYPE_TEXT_VARIATION_PASSWORD
أحد أشكال TYPE_CLASS_TEXT لإدخال كلمات المرور تعرِض طريقة الإدخال رموز Dingbats بدلاً من النص الفعلي.
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() للمفاتيح التي لا تريد التعامل معها بنفسك.

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

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

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

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

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

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

<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 لنظام معالجة النصوص (IME). يتم تعريف مورد السلسلة label_subtype_generic، الذي يستخدمه تعريف واجهة مستخدم طريقة الإدخال لضبط علامة النوع الفرعي، على النحو التالي:

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

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

اختيار أنواع تطبيقات تحسين الكتابة من شريط الإشعارات

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

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

اختيار أنواع تطبيقات تحسين الكتابة من إعدادات النظام

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

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