1. מבוא
ב-Android בגרסה 10 ואילך, תנועות ניווט נתמכות כמצב חדש. כך האפליקציה יכולה להשתמש בכל המסך ולספק חוויית תצוגה עשירה יותר. כשמשתמש מחליק למעלה מהקצה התחתון של המסך, הוא מועבר למסך הבית של Android. כשהמשתמשים מחליקים פנימה מהקצה השמאלי או הימני, הם מועברים למסך הקודם.
באמצעות שתי התנועות האלה, האפליקציה יכולה לנצל את השטח של המסך שבתחתית המסך. עם זאת, אם האפליקציה משתמשת בתנועות או כוללת אמצעי בקרה באזורים של תנועות במערכת, היא עלולה ליצור התנגשות עם תנועות שמופיעות במערכת.
המטרה של ה-Codelab הזו היא ללמד אותך איך להשתמש בערכות חדשות כדי למנוע התנגשות בין תנועות. בנוסף, המטרה של ה-codelabs הזו היא ללמד איך להשתמש ב-תנועות להחרגת תנועות כדי להשתמש באמצעי בקרה כמו נקודות אחיזה לגרירה, שצריכים להיות באזורים של התנועות.
מה תלמד ללמוד
- איך להשתמש ב-Inset listers בצפיות
- איך משתמשים ב-API של החרגת תנועות
- איך פועל מצב של צפייה היקפית כשהתנועות פעילות
המטרה של ה-Codelab הזו היא שהאפליקציה שלך תהיה תואמת לתנועות מערכת. מונחים לא רלוונטיים ובלוקים של קוד עם הפרדה מבריקה, ניתנים להעתקה ולהדבקה.
מה תפַתחו
נגן המוזיקה האוניברסלי של Android (UAMP) הוא אפליקציה לדוגמה של נגן מוזיקה ל-Android שנכתבה ב-Kotlin. צריך להגדיר UAMP לניווט באמצעות תנועות.
- אפשר להשתמש בתוספים כדי להרחיק פקדים מאזורי תנועות
- שימוש ב-תנועות החרגת תנועות כדי לבטל את ההסכמה לתנועת החזרה עבור פקדים שמתנגשים
- משתמשים בגרסאות ה-build כדי לגלות שינויים בהתנהגות במצב של צפייה היקפית בעזרת ניווט באמצעות תנועות
מה צריך להכין
- מכשיר או אמולטור עם Android מגרסה 10 ואילך
- ב-Android Studio
2. סקירה כללית של האפליקציה
נגן המוזיקה האוניברסלי של Android (UAMP) הוא אפליקציה לדוגמה של נגן מוזיקה ל-Android שנכתבה ב-Kotlin. הוא תומך בתכונות כמו הפעלה ברקע, טיפול בפוקוס אודיו, שילוב של Assistant ובכמה פלטפורמות כמו Wear, טלוויזיה ו-Auto.
איור 1: תהליך ב-UAMP
UAMP טוען קטלוג מוזיקה משרת מרוחק ומאפשר למשתמש לעיין באלבומים ובשירים. המשתמש מקיש על שיר והוא מושמע באוזניות או ברמקולים מחוברים. האפליקציה לא מיועדת לפעול עם תנועות מערכת. לכן, כשמריצים UAMP במכשיר עם Android מגרסה 10 ואילך, נתקלים בבעיות בהתחלה.
3. להגדרה
כדי לקבל את האפליקציה לדוגמה, משכפלים את המאגר מ-GitHub ועוברים להסתעפות starter:
$ git clone https://github.com/googlecodelabs/android-gestural-navigation/
לחלופין, אפשר להוריד את המאגר כקובץ ZIP, לחלץ את המאגר ולפתוח אותו ב-Android Studio.
כך עושים את זה:
- פותחים ויוצרים את האפליקציה ב-Android Studio.
- יוצרים מכשיר וירטואלי חדש ובוחרים באפשרות רמת API 29. לחלופין, אפשר לחבר מכשיר אמיתי עם API ברמה 29 ומעלה.
- מפעילים את האפליקציה. הרשימה שבה רואים את השירים מקבצת אותה באפשרויות מומלצים ואלבומים.
- לוחצים על מומלצים ובוחרים שיר מרשימת השירים.
- האפליקציה מתחילה להפעיל את השיר.
הפעלת ניווט באמצעות תנועות
אם מפעילים מופע אמולטור חדש עם רמת API 29, יכול להיות שהניווט באמצעות תנועות לא מופעל כברירת מחדל. כדי להפעיל ניווט באמצעות תנועות, בוחרים באפשרות הגדרות מערכת > מערכת > ניווט במערכת > ניווט באמצעות תנועות.
הפעלת האפליקציה באמצעות ניווט באמצעות תנועות
אם הפעלתם את האפליקציה כשהתכונה 'ניווט באמצעות תנועות' מופעלת ותתחילו להשמיע שיר, יכול להיות שתבחינו שלחצני הנגן קרובים מאוד לאזורי הבית ולאזורי תנועות החזרה.
4. מעבר מקצה לקצה
מה זה מקצה לקצה?
אפליקציות שפועלות ב-Android 10 ואילך יכולות לספק חוויית שימוש במסך מקצה לקצה, גם אם התנועות או הלחצנים מופעלים לניווט. כדי להציע חוויית שימוש מקצה לקצה, האפליקציות שלכם חייבות לשרטט מאחורי הניווט השקוף וסרגלי הסטטוס.
שרטוט מאחורי סרגל הניווט
כדי שהאפליקציה שלך תעבד תוכן מתחת לסרגל הניווט, קודם צריך להפוך את הרקע של סרגל הניווט לשקוף. לאחר מכן, שורת הסטטוס צריכה להיות שקופה. כך האפליקציה יכולה להציג את האפליקציה לכל גובה המסך.
כדי לשנות את הצבע של סרגל הניווט ואת הצבע של שורת הסטטוס, מבצעים את השלבים הבאים:
- סרגל הניווט: פותחים את
res/values-29/styles.xml
ומגדירים אתnavigationBarColor
ל-color/transparent
. - שורת סטטוס: באופן דומה, מגדירים את
statusBarColor
לערךcolor/transparent
.
כדאי לבדוק את דוגמת הקוד הבאה של res/values-29/styles.xml
:
<!-- change navigation bar color -->
<item name="android:navigationBarColor">
@android:color/transparent
</item>
<!-- change status bar color -->
<item name="android:statusBarColor">
@android:color/transparent
</item>
סימונים להרשאות גישה לממשק המשתמש של המערכת
בנוסף, צריך להגדיר את סימוני החשיפה של ממשק המשתמש של המערכת כדי להנחות את המערכת לפרוס את האפליקציה מתחת לסרגלי המערכת. ממשקי ה-API של systemUiVisibility
במחלקה View
מאפשרים להגדיר מגוון של דגלים. כך עושים את זה:
- פותחים את הכיתה
MainActivity.kt
ומוצאים את השיטהonCreate()
. מקבלים מופע שלfragmentContainer
. - מגדירים את הערך הבא בתור
content.systemUiVisibility
:
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
כדאי לבדוק את דוגמת הקוד הבאה של MainActivity.kt
:
val content: FrameLayout = findViewById(R.id.fragmentContainer)
content.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
כשאתם מגדירים את כל הסימונים האלה ביחד, אתם מגדירים למערכת שאתם רוצים שהאפליקציה שלכם תוצג במסך מלא כאילו ששורת הניווט ושורת הסטטוס לא מופיעות. כך עושים את זה:
- מפעילים את האפליקציה וכדי לעבור למסך הנגן, בוחרים את השיר שרוצים לשמוע.
- מוודאים שלחצני הנגן מוצגים מתחת לסרגל הניווט, מה שמקשה על הגישה אליהם:
- עוברים אל הגדרות המערכת, חוזרים למצב הניווט עם שלושה לחצנים וחוזרים לאפליקציה.
- מוודאים שקשה עוד יותר להשתמש בפקדים באמצעות סרגל הניווט של שלושת הלחצנים: שימו לב שה-
SeekBar
מוסתר מאחורי סרגל הניווט ושסרגל הניווט מכוסה ברובו על ידי הפעלה/השהיה. - כדאי לחקור ולהתנסות קצת. בסיום, מנווטים אל הגדרות המערכת וחוזרים אל 'ניווט באמצעות תנועות':
האפליקציה מוצגת עכשיו מקצה לקצה, אבל יש בעיות בנוחות השימוש, אפשרות לקבוע אילו התנגשויות וחפיפה באפליקציה, וצריך לפתור אותן.
5. Inset
WindowInsets
מציין לאפליקציה איפה ממשק המשתמש של המערכת מופיע מעל התוכן שלכם, ולאילו אזורים במסך יש עדיפות לתנועות מערכת על פני תנועות בתוך האפליקציה. רכיבי inset מיוצגים על ידי המחלקה WindowInsets
והמחלקה WindowInsetsCompat
ב-Jetpack. מומלץ מאוד להשתמש ב-WindowInsetsCompat
כדי להתנהל באופן עקבי בכל רמות ה-API.
כניסות למערכת והטמעות מערכת חיוניות
ממשקי ה-API הבאים המשולבים הם סוגי ההטמעה הנפוצים ביותר:
- כניסות לחלון המערכת: הן מאפשרות לכם לדעת איפה ממשק המשתמש של המערכת מוצג מעל האפליקציה שלכם. נסביר איך תוכלו להשתמש ברכיבי inset של המערכת כדי להרחיק את הפקדים מסרגלי המערכת.
- insets של תנועות במערכת: הם מחזירים את כל האזורים של תנועות. פקדי החלקה בתוך האפליקציה באזורים האלה עלולים להפעיל בטעות תנועות מערכת.
- שילובים של תנועות חובה: הן קבוצת משנה של תנועות מובנות במערכת, ואי אפשר לשנות אותן. הם מציינים באילו אזורים במסך שבהם ההתנהגות של תנועות המערכת תמיד תקבל עדיפות על פני תנועות בתוך האפליקציה.
שימוש ב-Insets כדי להעביר פקדים של אפליקציות
עכשיו, אחרי שהבנתם מידע נוסף על ממשקי API מוגדרים, אתם יכולים לתקן את אמצעי הבקרה של האפליקציות, כמו שמתואר בשלבים הבאים:
- מקבלים מופע של
playerLayout
ממופע האובייקטview
. - מוסיפים
OnApplyWindowInsetsListener
אלplayerView
. - מרחיקים את התצוגה מאזור התנועה: מאתרים את הערך המובנה במערכת בחלק התחתון ומגדילים את המרווח הפנימי של התצוגה בסכום הזה. כדי לעדכן את המרווח הפנימי של התצוגה בהתאם, ל[ערך המשויך למרווח הפנימי התחתון של האפליקציה], מוסיפים [הערך המשויך לערך התחתון של המערכת].
כדאי לבדוק את דוגמת הקוד הבאה של NowPlayingFragment.kt
:
playerView = view.findViewById(R.id.playerLayout)
playerView.setOnApplyWindowInsetsListener { view, insets ->
view.updatePadding(
bottom = insets.systemWindowInsetBottom + view.paddingBottom
)
insets
}
- מפעילים את האפליקציה ובוחרים שיר. שימו לב שלא נראה שום שינוי בלחצני הנגן. אם מוסיפים נקודת עצירה (breakpoint) ומריצים את האפליקציה בניפוי באגים, רואים שלא מתבצעת קריאה ל-listener.
- כדי לפתור את הבעיה, צריך לעבור אל
FragmentContainerView
, שמטפל בבעיה הזו באופן אוטומטי. פותחים אתactivity_main.xml
ומשנים אתFrameLayout
ל-FragmentContainerView
.
כדאי לבדוק את דוגמת הקוד הבאה של activity_main.xml
:
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragmentContainer"
tools:context="com.example.android.uamp.MainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- מפעילים שוב את האפליקציה ומנווטים למסך הנגן. לחצני הנגן התחתונים מוסרים מאזור התנועות התחתון.
פקדי האפליקציה פועלים עכשיו עם ניווט באמצעות תנועות, אבל הפקדים זזים יותר מהצפוי. עליך לפתור את הבעיה.
שמירה על המרווח הפנימי והשוליים הנוכחיים
אם עוברים לאפליקציות אחרות או עוברים למסך הבית וחוזרים לאפליקציה בלי לסגור את האפליקציה, שימו לב שלחצני הנגן זזים למעלה בכל פעם.
הסיבה לכך היא שהאפליקציה מפעילה requestApplyInsets()
בכל פעם שהפעילות מתחילה. גם בלי השיחה הזו, ניתן לשלוח את המספר WindowInsets
כמה פעמים בכל שלב במהלך מחזור החיים של צפייה.
הערך הנוכחי של InsetListener
ב-playerView
פועל בצורה מושלמת בפעם הראשונה כשמוסיפים את ערך הערך התחתון הפנימי לערך המרווח הפנימי התחתון של האפליקציה שהוצהר ב-activity_main.xml
. עם זאת, הקריאות הבאות ימשיכו להוסיף את הערך התחתון המוכנס למרווח הפנימי התחתון של התצוגה שכבר עודכנה.
כדי לפתור את הבעיה, מבצעים את השלבים הבאים:
- מתעדים את הערך המרווח הפנימי של התצוגה הראשונית. יצירת ערך חדש ואחסון ערך המרווח הפנימי של התצוגה הראשונית של
playerView
, ממש לפני קוד ה-listen.
כדאי לבדוק את דוגמת הקוד הבאה של NowPlayingFragment.kt
:
val initialPadding = playerView.paddingBottom
- אפשר להשתמש בערך הראשוני הזה כדי לעדכן את המרווח הפנימי התחתון בתצוגה, וכך להימנע משימוש בערך המרווח הפנימי התחתון הנוכחי של האפליקציה.
כדאי לבדוק את דוגמת הקוד הבאה של NowPlayingFragment.kt
:
playerView.setOnApplyWindowInsetsListener { view, insets ->
view.updatePadding(bottom = insets.systemWindowInsetBottom + initialPadding)
insets
}
- מפעילים שוב את האפליקציה. עוברים בין האפליקציות ועוברים למסך הבית. כשמחזירים את האפליקציה, לחצני הנגן נמצאים ממש מעל אזור התנועות.
עיצוב מחדש של פקדי האפליקציות
סרגל הדילוג של הנגן קרוב מדי לאזור התנועות התחתון. כלומר, המשתמש יכול להפעיל בטעות את תנועת המעבר למסך הבית במהלך החלקה אופקית. אם תגדילו עוד יותר את המרווח הפנימי, הפעולה הזו יכולה לטפל בבעיה, אבל גם תעביר את הנגן למיקום גבוה יותר מהרצוי.
השימוש בעיצובים פנימיים מאפשר לתקן התנגשויות בין תנועות, אבל לפעמים, אם מבצעים שינויים קטנים בעיצוב, אפשר למנוע לחלוטין התנגשויות תנועות. כדי לעצב מחדש את לחצני הנגן כדי למנוע התנגשות בין תנועות, מבצעים את השלבים הבאים:
- פתיחת
fragment_nowplaying.xml
. עוברים לתצוגת עיצוב ובוחרים בסמלSeekBar
מלמטה:
- מעבר לתצוגת קוד.
- כדי להעביר את
SeekBar
לחלק העליון שלplayerLayout
, צריך לשנות אתlayout_constraintTop_toBottomOf
של ה-SeekBar ל-parent
. - כדי להגביל פריטים אחרים ב
playerView
לחלק התחתון שלSeekBar
, יש לשנות אתlayout_constraintTop_toTopOf
מהורה ל-@+id/seekBar
ב-media_button
,title
וב-position
.
כדאי לבדוק את דוגמת הקוד הבאה של fragment_nowplaying.xml
:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:layout_gravity="bottom"
android:background="@drawable/media_overlay_background"
android:id="@+id/playerLayout">
<ImageButton
android:id="@+id/media_button"
android:layout_width="@dimen/exo_media_button_width"
android:layout_height="@dimen/exo_media_button_height"
android:background="?attr/selectableItemBackground"
android:scaleType="centerInside"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/seekBar"
app:srcCompat="@drawable/ic_play_arrow_black_24dp"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Title"
app:layout_constraintTop_toTopOf="@+id/seekBar"
app:layout_constraintLeft_toRightOf="@id/media_button"
app:layout_constraintRight_toLeftOf="@id/position"
tools:text="Song Title" />
<TextView
android:id="@+id/subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Subtitle"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintLeft_toRightOf="@id/media_button"
app:layout_constraintRight_toLeftOf="@id/position"
tools:text="Artist" />
<TextView
android:id="@+id/position"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Title"
app:layout_constraintTop_toTopOf="@+id/seekBar"
app:layout_constraintRight_toRightOf="parent"
tools:text="0:00" />
<TextView
android:id="@+id/duration"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Subtitle"
app:layout_constraintTop_toBottomOf="@id/position"
app:layout_constraintRight_toRightOf="parent"
tools:text="0:00" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- מפעילים את האפליקציה ויוצרים אינטראקציה עם הנגן ועם סרגל הדילוג.
השינויים המינימליים האלה בעיצוב משפרים משמעותית את האפליקציה.
6. ממשק API להחרגה של תנועות
לחצני הנגן להתנגשות בין תנועות באזור התנועות במסך הבית קבועים. האזור של תנועות החזרה יכול גם ליצור התנגשויות עם הפקדים של האפליקציה. בצילום המסך הבא אפשר לראות שסרגל הדילוג של הנגן נמצא כרגע באזור של התנועות ימינה ושמאלה אחורה:
SeekBar
מטפל באופן אוטומטי בהתנגשויות בין תנועות. אבל יכול להיות שתצטרכו להשתמש ברכיבים אחרים בממשק המשתמש שמפעילים התנגשות בין תנועות. במקרים כאלה, תוכלו להשתמש ב-Gesture Exclusion API
כדי לבטל באופן חלקי את תנועת החזרה.
שימוש בממשק API של החרגת תנועות
כדי ליצור אזור להחרגת תנועה, צריך לקרוא לפונקציה setSystemGestureExclusionRects()
בתצוגה עם רשימה של rect
אובייקטים. האובייקטים rect
ממופים לקואורדינטות של אזורי המלבנים שלא נכללים. צריך לבצע את הקריאה הזו ב-methods onLayout()
או onDraw()
של התצוגה. כדי לעשות זאת:
- יוצרים חבילה חדשה בשם
view
. - כדי לשלוח קריאה ל-API הזה, צריך ליצור מחלקה חדשה בשם
MySeekBar
ולהרחיב את הגישה אלAppCompatSeekBar
.
כדאי לבדוק את דוגמת הקוד הבאה של MySeekBar.kt
:
class MySeekBar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = android.R.attr.seekBarStyle
) : androidx.appcompat.widget.AppCompatSeekBar(context, attrs, defStyle) {
}
- יוצרים שיטה חדשה בשם
updateGestureExclusion()
.
כדאי לבדוק את דוגמת הקוד הבאה של MySeekBar.kt
:
private fun updateGestureExclusion() {
}
- אפשר להוסיף בדיקה כדי לדלג על השיחה הזו ברמת API 28 ומטה.
כדאי לבדוק את דוגמת הקוד הבאה של MySeekBar.kt
:
private fun updateGestureExclusion() {
// Skip this call if we're not running on Android 10+
if (Build.VERSION.SDK_INT < 29) return
}
- מכיוון שלממשק ה-API של החרגת תנועות מוגבל ל-200dp, צריך להחריג רק את האגודל בסרגל הדילוג. מקבלים עותק של הגבולות של סרגל הדילוג ומוסיפים כל אובייקט לרשימה שניתנת לשינוי.
כדאי לבדוק את דוגמת הקוד הבאה של MySeekBar.kt
:
private val gestureExclusionRects = mutableListOf<Rect>()
private fun updateGestureExclusion() {
// Skip this call if we're not running on Android 10+
if (Build.VERSION.SDK_INT < 29) return
thumb?.also { t ->
gestureExclusionRects += t.copyBounds()
}
}
- התקשרות אל
systemGestureExclusionRects()
באמצעות הרשימות שלgestureExclusionRects
שיצרת.
כדאי לבדוק את דוגמת הקוד הבאה של MySeekBar.kt
:
private val gestureExclusionRects = mutableListOf<Rect>()
private fun updateGestureExclusion() {
// Skip this call if we're not running on Android 10+
if (Build.VERSION.SDK_INT < 29) return
thumb?.also { t ->
gestureExclusionRects += t.copyBounds()
}
// Finally pass our updated list of rectangles to the system
systemGestureExclusionRects = gestureExclusionRects
}
- אפשר להפעיל את השיטה
updateGestureExclusion()
באמצעותonDraw()
אוonLayout()
. ביטולonDraw()
והוספת קריאה ל-updateGestureExclusion
.
כדאי לבדוק את דוגמת הקוד הבאה של MySeekBar.kt
:
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
updateGestureExclusion()
}
- עליך לעדכן את ההפניות של
SeekBar
. כדי להתחיל, פותחים אתfragment_nowplaying.xml
. - שינוי
SeekBar
לcom.example.android.uamp.view.MySeekBar
.
כדאי לבדוק את דוגמת הקוד הבאה של fragment_nowplaying.xml
:
<com.example.android.uamp.view.MySeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
- כדי לעדכן את ההפניות
SeekBar
ב-NowPlayingFragment.kt
, פותחים אתNowPlayingFragment.kt
ומשנים את הסוג שלpositionSeekBar
ל-MySeekBar
. כדי להתאים את סוג המשתנה, צריך לשנות את הגנריקה שלSeekBar
בקריאהfindViewById
ל-MySeekBar
.
כדאי לבדוק את דוגמת הקוד הבאה של NowPlayingFragment.kt
:
val positionSeekBar: MySeekBar = view.findViewById<MySeekBar>(
R.id.seekBar
).apply { progress = 0 }
- אפשר להפעיל את האפליקציה וליצור אינטראקציה עם
SeekBar
. אם אתם עדיין נתקלים בהתנגשויות בתנועות, תוכלו לנסות לשנות את גבולות האגודל ב-MySeekBar
. חשוב להיזהר לא ליצור אזור החרגה של תנועה גדול מהנדרש, כי הפעולה הזו מגבילה קריאות פוטנציאליות להחרגת תנועה ויוצרת התנהגות לא עקבית של המשתמשים.
7. מזל טוב
מעולה! למדת איך למנוע התנגשויות ולפתור אותן באמצעות תנועות במערכת.
גרמתם לכך שהאפליקציה תשתמש במסך מלא כשהרחבתם מקצה לקצה והשתמשת ברכיבי inset כדי להרחיק את לחצני האפליקציה מאזורי התנועות. למדנו גם איך להשבית את תנועת החזרה של המערכת בפקדים של האפליקציות.
עכשיו ידוע מהם השלבים העיקריים שנדרשים כדי שהאפליקציות שלך יפעלו עם תנועות במערכת.
חומרי לימוד נוספים
- WindowInsets – האזנה לפריסות
- ניווט באמצעות תנועות: מעבר מקצה לקצה
- ניווט באמצעות תנועות: טיפול בחפיפה בין רכיבים חזותיים
- ניווט באמצעות תנועות: טיפול בהתנגשויות בין תנועות
- הבטחת תאימות לניווט באמצעות תנועות