עורך שיטות קלט (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:
זוהי הממשק ש-Latin 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, כדאי להשתמש בתכונת תת-הסוג, כי היא עוזרת למשתמש לזהות את השפות והמצבים השונים של ה-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 צריך לספק הרבה תווים שונים כדי לאפשר למשתמשים להזין סיסמה ולגשת למכשיר.