עורך שיטות קלט (IME) הוא אמצעי בקרה למשתמשים שמאפשר להם להזין טקסט. מערכת Android מספקת מסגרת ניתנת להרחבה של שיטות קלט, שמאפשרת לאפליקציות לספק למשתמשים שיטות קלט חלופיות, כמו מקלדות וירטואליות או קלט קולי. אחרי התקנת ה-IME, המשתמש יכול לבחור אחד מהם בהגדרות המערכת ולהשתמש בו בכל המערכת. אפשר להפעיל רק IME אחד בכל פעם.
כדי להוסיף IME למערכת Android, צריך ליצור אפליקציה ל-Android שמכילה מחלקה שמרחיבה את InputMethodService.
בנוסף, בדרך כלל יוצרים פעילות מסוג 'הגדרות' שמעבירה אפשרויות לשירות IME. אפשר גם להגדיר ממשק משתמש להגדרות שיוצג כחלק מהגדרות המערכת.
בדף הזה מפורטים הנושאים הבאים:
- מחזור החיים של IME
- הצהרה על רכיבי IME במניפסט של האפליקציה
- The IME API
- עיצוב ממשק משתמש של IME
- שליחת טקסט מ-IME לאפליקציה
- עבודה עם סוגי משנה של IME
- שיקולים נוספים לגבי IME
אם לא עבדתם עם IMEs, מומלץ לקרוא קודם את מאמר המבוא שיטות קלט במסך.
מחזור החיים של IME
בתרשים הבא מתואר מחזור החיים של 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 מוצג בפעם הראשונה, המערכת קוראת ל-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 אם לא רוצים להציג כלום. התנהגות ברירת המחדל היא תגובה ריקה, כך שלא צריך להטמיע את זה אם לא מספקים הצעות.
שיקולים בעיצוב ממשק המשתמש
בקטע הזה מתוארים כמה שיקולים לעיצוב ממשק משתמש עבור 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()
- Commits a
CharSequenceto the text field and sets a new cursor position.
לדוגמה, בקטע הקוד הבא מוצג איך להחליף את ארבעת התווים שמשמאל לסמן בטקסט '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 על ידי הוספת מקש מעבר, כמו סמל השפה בצורת גלובוס במקלדת. כך נוח יותר להשתמש במקלדת, וזה גם שימושי למשתמשים. כדי להפעיל את האפשרות הזו, פועלים לפי השלבים הבאים:
- מצהירים על
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">
- מבצעים קריאה ל-
shouldOfferSwitchingToNextInputMethod(). - אם השיטה מחזירה true, מוצג מקש מעבר.
- כשהמשתמש מקיש על מקש ההחלפה, השיחה
switchToNextInputMethod(), מועברת כ-false. הערך false אומר למערכת להתייחס לכל סוגי המשנה באופן שווה, בלי קשר ל-IME שאליהם הם שייכים. אם מציינים True, המערכת עוברת בין סוגי משנה ב-IME הנוכחי.
שיקולים כלליים לגבי IME
אלה עוד דברים שכדאי לקחת בחשבון כשמטמיעים את ה-IME:
- לספק למשתמשים דרך להגדיר אפשרויות ישירות מממשק המשתמש של ה-IME.
- צריך לספק למשתמשים דרך לעבור ל-IME אחר ישירות מממשק המשתמש של שיטת הקלט, כי יכול להיות שמספר IME מותקנים במכשיר.
- הצגת ממשק המשתמש של IME במהירות. כדאי לטעון מראש או לפי דרישה משאבים גדולים כדי שהמשתמשים יראו את ה-IME ברגע שהם מקישים על שדה טקסט. שמירת משאבים ותצוגות במטמון להפעלות הבאות של שיטת הקלט.
- צריך לשחרר הקצאות גדולות של זיכרון מיד אחרי שחלון שיטת הקלט מוסתר, כדי שלאפליקציות יהיה מספיק זיכרון לפעולה. משתמשים בהודעה מושהית כדי לשחרר משאבים אם ה-IME מוסתר למשך כמה שניות.
- מוודאים שהמשתמשים יכולים להזין כמה שיותר תווים בשפה או באזור שמשויכים ל-IME. יכול להיות שמשתמשים ישתמשו בסימני פיסוק בסיסמאות או בשמות משתמש, ולכן שיטת הקלט (IME) צריכה לספק הרבה תווים שונים כדי לאפשר למשתמשים להזין סיסמה ולגשת למכשיר.