הגישה של שיטות הקלט

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

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

הצגת המקלדת הרכה כשהפעילות מתחילה

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

כדי להציג את שיטת הקלט כשהפעילות מתחילה, צריך להוסיף את android:windowSoftInputMode רכיב <activity> עם הערך "stateVisible". לדוגמה:

<application ... >
    <activity
        android:windowSoftInputMode="stateVisible" ... >
        ...
    </activity>
   ...
</application>

מציינים איך ממשק המשתמש צריך להגיב

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

כדי להצהיר על הטיפול המועדף בפעילות מסוימת, צריך להשתמש מאפיין android:windowSoftInputMode ברכיב <activity> של המניפסט עם אחת מפעולות הכוונון ערכים.

לדוגמה, כדי להבטיח שהמערכת תשנה את גודל הפריסה כך שכל תוכן הפריסה שלך נגיש, גם אם נדרשת גלילה — יש להשתמש ב-"adjustResize":

<application ... >
   <activity
       android:windowSoftInputMode="adjustResize" ... >
       ...
   </activity>
   ...
</application>

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

<activity
    android:windowSoftInputMode="stateVisible|adjustResize" ... >
    ...
</activity>

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

הצגת המקלדת הרכה על פי דרישה

אם יש שיטה במחזור החיים של הפעילות שבה אתם רוצים לוודא של שיטת הקלט, אפשר להשתמש InputMethodManager כדי להציג אותה.

לדוגמה, השיטה הבאה מתייחסת View שבו המשתמש צפוי להקליד משהו, להתקשר requestFocus() לתת אותו פוקוס, ואז קורא ל-showSoftInput() כדי לפתוח את שיטת הקלט:

Kotlin

fun showSoftKeyboard(view: View) {
   if (view.requestFocus()) {
       val imm = getSystemService(InputMethodManager::class.java)
       imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
   }
}

Java

public void showSoftKeyboard(View view) {
   if (view.requestFocus()) {
       InputMethodManager imm = getSystemService(InputMethodManager.class);
       imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
   }
}

הצגת המקלדת הרכה באופן מהימן

יש מצבים מסוימים, למשל מתי מתחילה פעילות, שבה שימוש ב-InputMethodManager.showSoftInput() כדי להציג את המקלדת עלולות לגרום לכך שמקלדת התוכנה לא תהיה גלויה למשתמש.

החשיפה של המקלדת הרכה בזמן השימוש ב-showSoftInput() מוגבלת בתנאים הבאים:

  • התצוגה חייבת להיות כבר מחוברת למקלדת התוכנה. (כתוצאה מכך, כדי להשתמש בכלי העריכה צריך להתמקד בחלון כדי לבקש את מיקוד התצוגה View.requestFocus()).

  • החשיפה יכולה להיות מושפעת גם מandroid:windowSoftInputMode והדגלים המשמשים את showSoftInput().

במקרים מסוימים, כמו כשפעילות מתחילה, חלק לא מתקיימים. המערכת לא מחשיבה את התצוגה בתור מחובר למקלדת התוכנה, מתעלם מהקריאה showSoftInput(), והמקלדת הרכה לא גלויה למשתמש.

כדי לוודא שמקלדת התוכנה מוצגת בצורה אמינה, אפשר להשתמש בפקודה הבאה חלופות:

  • (מומלץ) שימוש WindowInsetsControllerCompat. האובייקט הזה מציגה את המקלדת הרכה במהלך Activity.onCreate() כמו שמוצג את קטע הקוד הבא. מובטח שהשיחה תתוזמן אחרי החלון הזה ממוקד.

Kotlin

editText.requestFocus()
WindowCompat.getInsetsController(window, editText)!!.show(WindowInsetsCompat.Type.ime())

Java

editText.requestFocus();
WindowCompat.getInsetsController(getWindow(), editText).show(WindowInsetsCompat.Type.ime());
  • פרסם מודעת הרצה. כך ניתן לוודא שהאפליקציה תמתין עד לקבלת אירוע של התמקדות בחלון View.onWindowFocusChanged() לפני השיחה showSoftInput()

Kotlin

class MyEditText : EditText() {
  ...
  override fun onWindowFocusChanged(hasWindowFocus: Boolean) {
    if (hasWindowFocus) {
      requestFocus()
      post {
        val imm: InputMethodManager = getSystemService(InputMethodManager::class.java)
        imm.showSoftInput(this, 0)
      }
    }
  }
}

Java

public class MyEditText extends EditText {
  ...
  @Override
  public void onWindowFocusChanged(boolean hasWindowFocus) {
    if (hasWindowFocus) {
      requestFocus();
      post(() -> {
        InputMethodManager imm = getSystemService(InputMethodManager.class);
        imm.showSoftInput(this, 0);
      });
    }
  }
}

טיפול זהיר בדגלים של הרשאות גישה בזמן ריצה

כאשר מחליפים את מצב החשיפה של המקלדת הרכה בזמן הריצה, צריך להקפיד לא לעבור מסמנים את הערכים ל-methods. לדוגמה, אם האפליקציה מצפה מקלדת רכה מופיעה בזמן ביצוע שיחה View.getWindowInsetsController().show(ime()) בActivity.onCreate() במהלך שהפעילות מתחילה, מפתחי האפליקציות צריכים להיזהר סימון SOFT_INPUT_STATE_HIDDEN או SOFT_INPUT_STATE_ALWAYS_HIDDEN במהלך ההפעלה הראשונית, למקרה שהמקלדת הרכה מוסתרת באופן בלתי צפוי.

בדרך כלל המערכת מסתירה את המקלדת הרכה באופן אוטומטי

ברוב המקרים, המערכת מטפלת בהסתרת המקלדת הרכה. הזה יכול להיות כל אחד מהמקרים הבאים:

  • המשתמש מסיים את המשימה בשדה הטקסט.
  • המשתמש מקיש על מקש 'הקודם' או לוחץ על תנועות החלקה עם הניווט 'הקודם'.
  • המשתמש מנווט לאפליקציה אחרת, והאפליקציה האחרת הוגדרה SOFT_INPUT_STATE_HIDDEN או SOFT_INPUT_STATE_ALWAYS_HIDDEN דגלים כשהתצוגה מתמקדת.

הסתרת המקלדת הרכה באופן ידני על סמך התנהגות המערכת הקודמת

במצבים מסוימים האפליקציה חייבת להסתיר את המקלדת החכמה באופן ידני – לדוגמה, כשהמיקוד בשדה הטקסט מאבד View.OnFocusChangeListener.onFocusChange חשוב להפעיל שיקול דעת בטכניקה הזו . סגירה של המקלדת הרכה באופן בלתי צפוי פוגעת בחוויית המשתמש.

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

  • המקלדת הרכה נחשבת שהוצגה באופן מפורש אחרי שיחה אל showSoftInput().

  • לעומת זאת, מקלדת רכה נחשבת להצגה מרומזת אחד מהתנאים הבאים:

    • המערכת הציגה את המקלדת הרכה בזמן שהחילו את android:windowSoftInputMode
    • האפליקציה שלך עברה SHOW_IMPLICIT אל showSoftInput()

בדרך כלל, המקלדת hideSoftInputFromWindow() מסתירה את המקלדת, ללא קשר איך הבקשה נשלחה, אבל עם HIDE_IMPLICIT_ONLY אפשר להגביל אותה רק לסגירה של מקלדת טקסט מרומזת.

הצגה של תיבת דו-שיח או תצוגת שכבת-על מעל המקלדת הרכה

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

האפליקציה שלך כוללת כמה אפשרויות, שאותן מתוארים בקטעים הבאים.

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

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

יצירה של תיבת דו-שיח

שימוש בFLAG_ALT_FOCUSABLE_IM התכונה הניסיונית של חלון הדו-שיח כדי להשאיר את תיבת הדו-שיח מעל המקלדת הרכה מניעת התמקדות במקלדת הרכה:

Kotlin

val content = TextView(this)
content.text = "Non-editable dialog on top of soft keyboard"
content.gravity = Gravity.CENTER
val builder = AlertDialog.Builder(this)
  .setTitle("Soft keyboard layering demo")
  .setView(content)
mDialog = builder.create()
mDialog!!.window!!
  .addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
mDialog!!.show()

Java

TextView content = new TextView(this);
content.setText("Non-editable dialog on top of soft keyboard");
content.setGravity(Gravity.CENTER);
final AlertDialog.Builder builder = new AlertDialog.Builder(this)
    .setTitle("Soft keyboard layering demo")
    .setView(content);
mDialog = builder.create();
mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM);
mDialog.show();

יצירה של תצוגת שכבת-על

יוצרים תצוגה של שכבת-על שמציינת TYPE_APPLICATION_OVERLAY סוג החלון וFLAG_ALT_FOCUSABLE_IM סימון חלון לפי הפעילות המטורגטת במקלדת הרכה.

Kotlin

val params = WindowManager.LayoutParams(
  width,  /* Overlay window width */
  height,  /* Overlay window height */
  WindowManager.LayoutParams.TYPE_APPLICATION, /* Overlay window type */
  WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */
    or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,  /* Allow touch event send to soft keyboard behind the overlay */
  PixelFormat.TRANSLUCENT
)
params.title = "Overlay window"
mOverlayView!!.layoutParams = params
windowManager.addView(mOverlayView, params)

Java

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    width, /* Overlay window width */
    height, /* Overlay window height */
    TYPE_APPLICATION, /* Overlay window type */
    FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */
        | FLAG_NOT_TOUCH_MODAL, /* Allow touch event send to soft keyboard behind the overlay */
    PixelFormat.TRANSLUCENT);
params.setTitle("Overlay window");
mOverlayView.setLayoutParams(params);
getWindowManager().addView(mOverlayView, params);

הצגה של תיבת דו-שיח או תצוגה מתחת למקלדת הרכה

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

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

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

יצירה של תיבת דו-שיח

כדי ליצור תיבת דו-שיח, מגדירים גם את הסמל FLAG_NOT_FOCUSABLE דגל החלון FLAG_ALT_FOCUSABLE_IM דגל חלון:

Kotlin

val content = TextView(this)
content.text = "Non-editable dialog behind soft keyboard"
content.gravity = Gravity.CENTER
val builder = AlertDialog.Builder(this)
  .setTitle("Soft keyboard layering demo")
  .setView(content)
mDialog = builder.create()
mDialog!!.window!!
  .addFlags(FLAG_NOT_FOCUSABLE or FLAG_ALT_FOCUSABLE_IM)
mDialog!!.show()

Java

TextView content = new TextView(this);
content.setText("Non-editable dialog behind soft keyboard");
content.setGravity(Gravity.CENTER);
final AlertDialog.Builder builder = new AlertDialog.Builder(this)
    .setTitle("Soft keyboard layering demo")
    .setView(content);

mDialog = builder.create();
mDialog.getWindow()
    .addFlags(FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
mDialog.show();

יצירה של תצוגת שכבת-על

כדי ליצור תצוגה של שכבת-על, מגדירים גם את המאפיין FLAG_NOT_FOCUSABLE דגל החלון FLAG_ALT_FOCUSABLE_IM דגל חלון:

Kotlin

val params = WindowManager.LayoutParams(
  width,  /* Overlay window width */
  height,  /* Overlay window height */
  WindowManager.LayoutParams.TYPE_APPLICATION,  /* Overlay window type */
  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
      or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
  PixelFormat.TRANSLUCENT
)
params.title = "Overlay window"
mOverlayView!!.layoutParams = params
windowManager.addView(mOverlayView, params)

Java

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    width, /* Overlay window width */
    height, /* Overlay window height */
    TYPE_APPLICATION, /* Overlay window type */
    FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM,
    PixelFormat.TRANSLUCENT);
params.setTitle("Overlay window");
mOverlayView.setLayoutParams(params);
getWindowManager().addView(mOverlayView, params);