יצירה של שיטת קלט

עורך שיטות קלט (IME) הוא פקד משתמש שמאפשר למשתמשים להזין טקסט. Android מספק מסגרת שיטת קלט ניתנת להרחבה שמאפשרת לאפליקציות לספק למשתמשים שיטות קלט חלופיות, למשל, מקלדות שמופיעות במסך או קלט דיבור. לאחר התקנת רכיבי ה-IME, המשתמש יכול לבחור אחד מתוך את הגדרות המערכת ולהשתמש בהן בכל המערכת. ניתן להפעיל רק IME אחד בכל פעם.

כדי להוסיף IME למערכת Android, צריך ליצור אפליקציה ל-Android שמכילה כיתה נמשך InputMethodService כמו כן, בדרך כלל יוצרים "הגדרות" פעילות שמעבירה אפשרויות לשירות ה-IME. שלך יכול גם לקבוע ממשק משתמש של הגדרות שמוצג כחלק מהגדרות המערכת.

בדף הזה מפורטים הנושאים הבאים:

אם לא עד עכשיו עבדתם עם IME, אתם יכולים לקרוא את מאמר המבוא. שיטות קלט במסך קודם.

מחזור החיים של IME

התרשים הבא מתאר את מחזור החיים של IME:

תמונה שמציגה את מחזור החיים של IME.
איור 1. מחזור החיים של IME.

הקטעים הבאים מתארים כיצד ליישם את ממשק המשתמש והקוד המשויכים ל-IME עוקב אחרי מחזור החיים הזה.

הצהרה על רכיבי IME במניפסט

במערכת Android, רכיב IME הוא אפליקציה ל-Android שמכילה שירות IME מיוחד. בקובץ המניפסט של האפליקציה יש להצהיר על השירות, לבקש את ההרשאות הדרושות, לספק מסנן Intent שתואם לפעולה action.view.InputMethod, ומספק מטא-נתונים שמגדיר את המאפיינים של ה-IME. בנוסף, כדי לספק ממשק הגדרות שמאפשר משתמש לשנות את ההתנהגות של ה-IME, אפשר להגדיר 'הגדרות' פעילות שאפשר להפעיל מתוך הגדרות המערכת.

קטע הקוד הבא מצהיר על שירות IME. הוא מבקש את ההרשאה BIND_INPUT_METHOD כדי לאפשר לשירות לחבר את ה-IME למערכת, מגדיר מסנן Intent שתואם לפעולה. 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 עבור 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 ישירות מממשק המשתמש שלו.

ה-API של שיטת הקלט

כיתות שספציפיות ל-IME נמצאות android.inputmethodservice וגם android.view.inputmethod חבילות. הכיתה KeyEvent היא חשוב לטיפול בתווי במקלדת.

החלק המרכזי של IME הוא רכיב שירות - מחלקה שמשתרעת InputMethodService נוסף על הטמעת מחזור החיים הרגיל של השירות, יש קריאות חוזרות (callbacks) של הזנה של ממשק המשתמש של ה-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() כשהוא יהיה מוכן להצגת תצוגת המועמדים. ביישום של השיטה הזו, מחזירים את המחרוזת פריסה שמציגה הצעות למילים, או מחזירה null אם לא רוצים להציג שום דבר. ערך null היא התנהגות ברירת המחדל, לכן אין צורך ליישם אותה אם לא מספקים הצעות.

שיקולים לעיצוב ממשק משתמש

בקטע הזה מתוארים כמה משיקולים לגבי עיצוב ממשק המשתמש ברכיבי IME.

לטפל בכמה גדלים של מסכים

ממשק המשתמש של ה-IME שלך חייב להיות מסוגל להתאים את הגודל לגדלים שונים של מסכים ולטפל גם לרוחב ובכיוונים לאורך. במצב IME שאינו מסך מלא, יש להשאיר מספיק מקום לאפליקציה הצגת שדה הטקסט וכל הקשר משויך, כך שלא יהיו יותר מחצי מהמסך ה-IME. במצב IME במסך מלא, זו לא בעיה.

טיפול בסוגי קלט שונים

שדות הטקסט ב-Android מאפשרים להגדיר סוג קלט ספציפי, כמו טקסט חופשי, מספרים, כתובות URL, כתובות אימייל ומחרוזות חיפוש. כשמטמיעים IME חדש, מזהים את סוג הקלט של כל רכיב ולספק את הממשק המתאים לכך. עם זאת, אתם לא חייבים להגדיר את ה-IME שלכם לבדוק אם המשתמש מזין טקסט חוקי לסוג הקלט. באחריות האפליקציה ששדה הטקסט נמצא בבעלותה.

לדוגמה, זהו הממשק שה-IME הלטיני מספק עבור הטקסט של פלטפורמת Android. קלט:

תמונה שבה מוצג קלט טקסט ב-IME לטיני
איור 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 לשדה הטקסט ומגדיר מיקום סמן חדש.

לדוגמה, קטע הקוד הבא מראה איך להחליף את ארבעת התווים שמימין סמן עם הטקסט "שלום!":

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 לחשוף מצבי קלט מרובים ושפות שנתמכות על ידי IME. סוג משנה יכול שמייצגים את

  • מקום, כמו en_US או fr_FR
  • שיטת קלט, כמו קול, מקלדת או כתב יד
  • סגנונות קלט, טפסים או מאפיינים אחרים שהם ספציפיים ל-IME, כגון 10 מקשים או QWERTY פריסות מקלדת

המצב יכול להיות כל טקסט, כמו 'מקלדת'. או 'קול'. סוג משנה יכול גם לחשוף שילוב כאלה.

פרטי סוג המשנה משמשים לתיבת דו-שיח למחליף IME, שזמינה מסרגל ההתראות. ולהגדרות IME. המידע גם מאפשר ל-framework להציג סוג משנה ספציפי של 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, כפי שמוצג באיור הבא:

תמונה שמציגה את השפות תפריט מערכת קלט
איור 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. אם השיטה מחזירה את הערך True, מציגים מפתח החלפה.
  4. כשהמשתמש יקיש על מקש ההחלפה, התקשר switchToNextInputMethod(), העברת FALSE. הערך False מורה למערכת להתייחס לכל סוגי המשנה באופן שווה, ללא קשר לאיזה IME הם שייכים. כדי לציין True, המערכת צריכה לעבור בין סוגי משנה ה-IME הנוכחי.

שיקולים כלליים לגבי IME

יש עוד נקודות שכדאי להביא בחשבון במהלך הטמעת ה-IME:

  • מתן דרך למשתמשים להגדיר אפשרויות ישירות מממשק המשתמש של ה-IME.
  • לספק למשתמשים דרך לעבור ל-IME אחר ישירות מממשק המשתמש של שיטת הקלט, כי ייתכן שהותקנו במכשיר כמה עורכי שיטות קלט (IME).
  • העלאת ממשק המשתמש של ה-IME במהירות. לטעון מראש או לטעון לפי דרישה משאבים גדולים, כדי שהמשתמשים לראות את ה-IME ברגע שמקישים על שדה טקסט. שמירה במטמון של משאבים ותצוגות מפורטות הפעלות של שיטת הקלט.
  • משחררים הקצאות זיכרון גדולות מיד לאחר הסתרת החלון של שיטת הקלט, כדי כך שיש לאפליקציות מספיק זיכרון לרוץ. שימוש בהודעה מתעכבת לשחרור משאבים אם ה-IME מוסתר למשך מספר שניות.
  • צריך לוודא שהמשתמשים יכולים להזין כמה שיותר תווים בהתאם לשפה או ללוקאל שמשויכים ל-IME. משתמשים עשויים להשתמש בסימני פיסוק בסיסמאות או בשמות משתמשים, ולכן ה-IME חייב לספק תווים רבים ושונים כדי לאפשר למשתמשים להזין סיסמה ולגשת במכשיר.