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

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

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

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

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

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

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

صورة تعرض دورة حياة أداة IME.
الشكل 1. مراحل استخدام أداة IME.

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

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

في نظام Android، أداة 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 مهمة للتعامل مع حروف لوحة المفاتيح.

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

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

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

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

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

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

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

جافا

@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 الأساسي:

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

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

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

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

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

لغة Kotlin

inputType and InputType.TYPE_MASK_CLASS

جافا

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

جافا

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

جافا

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

اعتراض الأحداث الرئيسية للأجهزة

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

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

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

إنشاء نوع فرعي لأداة IME

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

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

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

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

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

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

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

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

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

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

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

صورة تعرض قائمة اختيار &quot;اللغات&quot;
الشكل 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. إذا أرجعت الطريقة القيمة true، اعرض مفتاح تبديل.
  4. عندما ينقر المستخدم على مفتاح التبديل، يتم استدعاء switchToNextInputMethod()، مع تمرير "خطأ". وتخبر القيمة false النظام بالتعامل مع كل الأنواع الفرعية بالتساوي، بغض النظر عن أداة IME التي تنتمي إليها. ويتطلب تحديد "صحيح" أن يتنقل النظام بين الأنواع الفرعية في أداة IME الحالية.

اعتبارات أداة IME العامة

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

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