באמצעות WindowInsetsCompat
, האפליקציה יכולה לשלוח שאילתות למקלדת שמופיעה במסך (שנקראת גם IME) ולשלוט בה, בדומה לאופן שבו היא מקיימת אינטראקציה עם סרגי המערכת. האפליקציה יכולה גם להשתמש ב-WindowInsetsAnimationCompat
כדי ליצור מעברים חלקים כשמקלדת התוכנה פתוחה או סגורה.
דרישות מוקדמות
לפני שמגדירים את אמצעי הבקרה והאנימציה של מקלדת התוכנה, צריך להגדיר את האפליקציה כך שתוצג מלאה. כך הוא יכול לטפל בחלונות משנה של מערכת, כמו סרגי המערכת והמקלדת במסך.
בדיקת הרשאות הגישה של תוכנת המקלדת
משתמשים ב-WindowInsets
כדי לבדוק את החשיפה של מקלדת התוכנה.
Kotlin
val insets = ViewCompat.getRootWindowInsets(view) ?: return val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()) val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
Java
WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(view); boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()); int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
לחלופין, אפשר להשתמש ב-ViewCompat.setOnApplyWindowInsetsListener
כדי להבחין בשינויים בהרשאות הגישה של מקלדת התוכנה.
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(view) { _, insets -> val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()) val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom insets }
Java
ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> { boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()); int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom; return insets; });
סנכרון האנימציה עם מקלדת התוכנה
משתמש שמקישים על שדה להזנת טקסט גורמת למקלדת להחליק אותה למקומה מתחתית המסך, כפי שמוצג בדוגמה הבאה:
הדוגמה עם התווית 'לא מסונכרן' באיור 2 מציגה את התנהגות ברירת המחדל ב-Android 10 (רמת API 29), שבה שדה הטקסט והתוכן של האפליקציה נעשים במקום להסתנכרן עם האנימציה של המקלדת – התנהגות שעשויה להיות קשה מבחינה ויזואלית.
ב-Android 11 (API ברמה 30) ואילך, אפשר להשתמש ב-
WindowInsetsAnimationCompat
כדי לסנכרן את המעבר של האפליקציה עם החלקה של המקלדת למעלה ולמטה מהחלק התחתון של המסך. התוצאה נראית חלקה יותר, כפי שמוצג בדוגמה שמסומנת בתווית 'סנכרון' באיור 2.
מגדירים את WindowInsetsAnimationCompat.Callback
כך שהתצוגה תסתנכרן עם אנימציית המקלדת.
Kotlin
ViewCompat.setWindowInsetsAnimationCallback( view, object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP) { // Override methods. } )
Java
ViewCompat.setWindowInsetsAnimationCallback( view, new WindowInsetsAnimationCompat.Callback( WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP ) { // Override methods. });
יש כמה שיטות לשינוי ברירת המחדל ב-WindowInsetsAnimationCompat.Callback
,
למשל
onPrepare()
,
onStart()
,
onProgress()
ו-onEnd()
.
מתחילים בקריאה ל-onPrepare()
לפני שמשנים את הפריסה.
onPrepare
נקרא כשאנימציה של תצוגה מוטמעת מתחילה, ולפני שהתצוגות מחדשות את הפריסה שלהן בגלל אנימציה. אפשר להשתמש בו כדי לשמור את מצב ההתחלה, שהוא במקרה הזה הקואורדינטה התחתונה של התצוגה.
קטע הקוד הבא מציג קריאה לדוגמה ל-onPrepare
:
Kotlin
var startBottom = 0f override fun onPrepare( animation: WindowInsetsAnimationCompat ) { startBottom = view.bottom.toFloat() }
Java
float startBottom; @Override public void onPrepare( @NonNull WindowInsetsAnimationCompat animation ) { startBottom = view.getBottom(); }
onStart
נקראת כשאנימציית ההוספה מתחילה. אפשר להשתמש בו כדי להגדיר את כל מאפייני התצוגה למצב הסיום של שינויי הפריסה. אם הגדרתם קריאה חוזרת OnApplyWindowInsetsListener
לאחת מהתצוגות, היא כבר נקראת בשלב הזה. זהו זמן טוב לשמור את מצב הסיום של מאפייני התצוגה.
קטע הקוד הבא מציג קריאה לדוגמה ל-onStart
:
Kotlin
var endBottom = 0f override fun onStart( animation: WindowInsetsAnimationCompat, bounds: WindowInsetsAnimationCompat.BoundsCompat ): WindowInsetsAnimationCompat.BoundsCompat { // Record the position of the view after the IME transition. endBottom = view.bottom.toFloat() return bounds }
Java
float endBottom; @NonNull @Override public WindowInsetsAnimationCompat.BoundsCompat onStart( @NonNull WindowInsetsAnimationCompat animation, @NonNull WindowInsetsAnimationCompat.BoundsCompat bounds ) { endBottom = view.getBottom(); return bounds; }
קוראים לפונקציה onProgress
כשרכיבי ה-Inset משתנים כחלק מהרצת אנימציה, כדי שאפשר יהיה לעקוף אותה ולקבל התראה בכל פריים במהלך האנימציה של המקלדת. מעדכנים את מאפייני התצוגה כך שהאנימציה של התצוגה תהיה מסונכרנת עם המקלדת.
בשלב הזה, כל השינויים בפריסה הושלמו. לדוגמה, אם משתמשים ב-View.translationY
כדי להזיז את התצוגה, הערך פוחת בהדרגה בכל קריאה ל-method הזה, ובסופו של דבר מגיע ל-0
כדי לחזור למיקום התצוגה המקורי.
קטע הקוד הבא מציג קריאה לדוגמה ל-onProgress
:
Kotlin
override fun onProgress( insets: WindowInsetsCompat, runningAnimations: MutableList<WindowInsetsAnimationCompat> ): WindowInsetsCompat { // Find an IME animation. val imeAnimation = runningAnimations.find { it.typeMask and WindowInsetsCompat.Type.ime() != 0 } ?: return insets // Offset the view based on the interpolated fraction of the IME animation. view.translationY = (startBottom - endBottom) * (1 - imeAnimation.interpolatedFraction) return insets }
Java
@NonNull @Override public WindowInsetsCompat onProgress( @NonNull WindowInsetsCompat insets, @NonNull List<WindowInsetsAnimationCompat> runningAnimations ) { // Find an IME animation. WindowInsetsAnimationCompat imeAnimation = null; for (WindowInsetsAnimationCompat animation : runningAnimations) { if ((animation.getTypeMask() & WindowInsetsCompat.Type.ime()) != 0) { imeAnimation = animation; break; } } if (imeAnimation != null) { // Offset the view based on the interpolated fraction of the IME animation. view.setTranslationY((startBottom - endBottom) * (1 - imeAnimation.getInterpolatedFraction())); } return insets; }
אפשר גם לשנות את onEnd
. ה-method הזה נקרא אחרי שהאנימציה מסתיימת. זה הזמן המתאים לבטל שינויים זמניים.
מקורות מידע נוספים
- WindowInsetsAnimation ב-GitHub.