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

בקטעים הבאים מוסבר איך להטמיע את ממשק המשתמש ואת הקוד שמשויכים ל-IME שפועל לפי מחזור החיים הזה.
הצהרה על רכיבי IME במניפסט
במערכת Android, IME היא אפליקציית Android שמכילה שירות IME מיוחד. בקובץ המניפסט של האפליקציה צריך להצהיר על השירות, לבקש את ההרשאות הנדרשות, לספק מסנן Intent שתואם לפעולה 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. יש לו מסנן 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 של שיטת הקלט
כיתות שספציפיות ל-IMEs נמצאות בחבילות
android.inputmethodservice
ו-
android.view.inputmethod
. המחלקות KeyEvent
חשובות לטיפול בתווים במקלדת.
החלק המרכזי של IME הוא רכיב שירות – מחלקה שמרחיבה את InputMethodService
. בנוסף להטמעה של מחזור החיים הרגיל של השירות, המחלקה הזו כוללת קריאות חוזרות (callbacks) לאספקת ממשק המשתמש של ה-IME, לטיפול בקלט מהמשתמש ולהעברת טקסט לשדה שמוצג. כברירת מחדל, המחלקה InputMethodService
מספקת את רוב ההטמעה לניהול המצב והחשיפה של ה-IME ולתקשורת עם שדה הקלט הנוכחי.
חשובות גם המחלקות הבאות:
BaseInputConnection
-
הגדרת ערוץ התקשורת מתוך
InputMethod
בחזרה לאפליקציה שמקבלת את הקלט שלה. משתמשים בו כדי לקרוא טקסט מסביב לסמן, להעביר טקסט לתיבת הטקסט ולשלוח אירועים גולמיים של מקשים לאפליקציה. אפליקציות צריכות להרחיב את המחלקה הזו במקום להטמיע את ממשק הבסיסInputConnection
. KeyboardView
-
תוסף של
View
שמציג מקלדת ומגיב לאירועי קלט של משתמשים. פריסת המקלדת מוגדרת על ידי מופע שלKeyboard
, שאפשר להגדיר בקובץ XML.
עיצוב ממשק המשתמש של שיטת הקלט
יש שני רכיבים חזותיים עיקריים ל-IME: תצוגת הקלט ותצוגת המועמדים. צריך להטמיע רק את הרכיבים שרלוונטיים לשיטת הקלט שאתם מתכננים.
תצוגת הקלט
תצוגת הקלט היא ממשק המשתמש שבו המשתמש מזין טקסט בצורה של הקשות על המקשים, כתב יד או תנועות. כש-IME מוצג בפעם הראשונה, המערכת קוראת ל-callback של
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, כך שלא צריך להטמיע את זה אם לא מספקים הצעות.
שיקולים בעיצוב ממשק המשתמש
בקטע הזה מתוארים כמה שיקולים לגבי עיצוב ממשק משתמש עבור IMEs.
טיפול במספר גדלים של מסכים
ממשק המשתמש של ה-IME צריך להיות רספונסיבי כדי להתאים לגדלים שונים של מסכים, ולתמוך בכיווני מסך לרוחב ולאורך. במצב IME שאינו מסך מלא, צריך להשאיר מספיק מקום כדי שהאפליקציה תוכל להציג את שדה הטקסט ואת ההקשר שקשור אליו, כך ש-IME לא יתפוס יותר ממחצית המסך. במצב IME במסך מלא, הבעיה הזו לא מתרחשת.
טיפול בסוגים שונים של קלט
בשדות טקסט ב-Android אפשר להגדיר סוג קלט ספציפי, כמו טקסט חופשי, מספרים, כתובות URL, כתובות אימייל ומחרוזות חיפוש. כשמטמיעים IME חדש, צריך לזהות את סוג הקלט של כל שדה ולספק את הממשק המתאים לו. עם זאת, אתם לא צריכים להגדיר את ה-IME כדי לבדוק אם המשתמש מזין טקסט תקין לסוג הקלט. האחריות לכך מוטלת על האפליקציה ששדה הטקסט שייך לה.
לדוגמה, זהו הממשק ש-IME ללטינית מספק להזנת טקסט בפלטפורמת Android:

וכאן מוצג הממשק ש-IME לטיני מספק לקלט מספרי בפלטפורמת Android:

כששדה קלט מקבל מיקוד ו-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()
- Commit של
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 לחשוף כמה מצבי קלט ושפות שנתמכים על ידי IME. סוג משנה יכול לייצג את הדברים הבאים:
- לוקאל, כמו en_US או fr_FR
- מצב קלט, כמו קול, מקלדת או כתב יד
- סגנונות קלט אחרים, טפסים או מאפיינים ספציפיים ל-IME, כמו פריסות של מקלדת עם 10 מקשים או מקלדת QWERTY
המצב יכול להיות כל טקסט, כמו 'מקלדת' או 'קול'. סוג משנה יכול גם לחשוף שילוב של אלה.
המידע על סוג המשנה משמש לתיבת דו-שיח להחלפת IME שזמינה מסרגל ההתראות ולהגדרות IME. המידע הזה מאפשר למסגרת להציג ישירות סוג משנה ספציפי של IME. כשיוצרים IME, מומלץ להשתמש בתכונה subtype, כי היא עוזרת למשתמש לזהות את השפות והמצבים השונים של ה-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, כמו שמוצג באיור הבא:

בחירה של סוגי משנה של IME מתוך הגדרות המערכת
המשתמש יכול גם לקבוע איך להשתמש בסוגי המשנה בחלונית ההגדרות שפה וקלט בהגדרות המערכת:

מעבר בין סוגי משנה של IME
אתם יכולים לאפשר למשתמשים לעבור בקלות בין סוגי משנה של IME על ידי הוספת מקש מעבר, כמו סמל השפה בצורת גלובוס במקלדת. כך משפרים את נוחות השימוש במקלדת, וזה נוח למשתמש. כדי להפעיל את האפשרות הזו, מבצעים את השלבים הבאים:
- מצהירים על
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">
- מבצעים קריאה ל-method
shouldOfferSwitchingToNextInputMethod()
. - אם השיטה מחזירה true, מוצג מקש מעבר.
- כשמשתמש מקיש על מקש המעבר, מתקבלת שיחה
switchToNextInputMethod()
, העברת הערך false. הערך false אומר למערכת להתייחס לכל סוגי המשנה באופן שווה, בלי קשר ל-IME שאליו הם שייכים. אם מציינים true, המערכת עוברת בין סוגי המשנה ב-IME הנוכחי.
שיקולים כלליים לגבי IME
אלה עוד דברים שכדאי לקחת בחשבון כשמטמיעים IME:
- לספק למשתמשים דרך להגדיר אפשרויות ישירות מממשק המשתמש של ה-IME.
- צריך לספק למשתמשים דרך לעבור ל-IME אחר ישירות מממשק המשתמש של שיטת הקלט, כי יכול להיות שמותקנים במכשיר כמה ממשקי IME.
- הצגה מהירה של ממשק המשתמש של IME. כדאי לטעון מראש או לפי דרישה משאבים גדולים, כדי שהמשתמשים יראו את ה-IME ברגע שהם מקישים על שדה טקסט. שמירת משאבים ותצוגות במטמון להפעלות הבאות של שיטת הקלט.
- צריך לשחרר הקצאות גדולות של זיכרון מיד אחרי שחלון שיטת הקלט מוסתר, כדי שלאפליקציות יהיה מספיק זיכרון לפעולה. משתמשים בהודעה מושהית כדי לשחרר משאבים אם ה-IME מוסתר למשך כמה שניות.
- מוודאים שהמשתמשים יכולים להזין כמה שיותר תווים בשפה או באזור שמשויכים ל-IME. יכול להיות שהמשתמשים ישתמשו בסימני פיסוק בסיסמאות או בשמות משתמש, ולכן ה-IME צריך לספק הרבה תווים שונים כדי לאפשר למשתמשים להזין סיסמה ולגשת למכשיר.