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

רוצה לנסות את שיטת הכתיבה?
'Jetpack פיתוח נייטיב' היא ערכת הכלים המומלצת לממשק המשתמש ל-Android. איך עובדים מקצה לקצה בניסוח אוטומטי.

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

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

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

איור 1. עמודות מערכת בפריסה מקצה לקצה.

כשמטמיעים פריסה מקצה לקצה באפליקציה, צריך לשמור את הפרטים הבאים חשוב:

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

הפעלת תצוגה מקצה לקצה

אם האפליקציה שלך מטרגטת SDK 35 ואילך, מקצה לקצה מופעל באופן אוטומטי עבור מכשירי Android מגרסה 15 ואילך.

כדי להפעיל מקצה לקצה בגרסאות Android קודמות, צריך לבצע את הפעולות הבאות:

  1. הוספת תלות androidx.activity קובץ build.gradle של האפליקציה או המודול:

    Kotlin

    dependencies {
        val activity_version = activity_version
        // Java language implementation
        implementation("androidx.activity:activity:$activity_version")
        // Kotlin
        implementation("androidx.activity:activity-ktx:$activity_version")
    }

    מגניב

    dependencies {
        def activity_version = activity_version
        // Java language implementation
        implementation 'androidx.activity:activity:$activity_version'
        // Kotlin
        implementation 'androidx.activity:activity-ktx:$activity_version'
    }
  2. ייבוא של enableEdgeToEdge את הפונקציה של תוסף לאפליקציה:

הפעלה ידנית מקצה לקצה באמצעות קריאה ל-enableEdgeToEdge ב-onCreate מתוך Activity שלך. הקריאה צריכה להיות לפני setContentView.

Kotlin

     override fun onCreate(savedInstanceState: Bundle?) {
       enableEdgeToEdge()
       super.onCreate(savedInstanceState)
       ...
     }
   

Java

     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
       EdgeToEdge.enable(this);
       super.onCreate(savedInstanceState);
       ...
     }
   

כברירת מחדל, enableEdgeToEdge() הופך את עמודות המערכת לשקיפות, למעט במצב מופעל מצב ניווט ב-3 לחצנים שבו בשורת הסטטוס מופיע מיסוך שקוף. הצבעים של סמלי המערכת והרקעים מותאמים בהתאם למערכת עיצוב בהיר או כהה.

הפונקציה enableEdgeToEdge() מצהירה באופן אוטומטי שהאפליקציה צריכה מסודר מקצה לקצה ומתאים את הצבעים של פסי המערכת.

כדי להפעיל תצוגה מקצה לקצה באפליקציה בלי להשתמש פונקציית enableEdgeToEdge(): מגדירים את התצוגה מקצה לקצה באופן ידני.

טיפול בחפיפות באמצעות inset

חלק מהתצוגות של האפליקציה עשויות להופיע מאחורי פסי המערכת, כפי שמוצג באיור 3.

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

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

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

  • כניסות מגרעת במסך: לאזורים שבהם עשוי להיות חיתוך מסך בגלל צורת המכשיר.

  • פעולות inset של תנועות במערכת: לאזורי ניווט באמצעות תנועות שבהם המערכת משתמשת שמקבלים עדיפות על פני האפליקציה שלכם.

רכיבי inset של פסים במערכת

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

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

דוגמה להטמעה מקצה לקצה, אבל סרגל הניווט מכסה את לחצן ה-FAB
איור 3. סרגל ניווט חופף ללחצן FAB ב- פריסה מקצה לקצה.

כדי להימנע מחפיפה חזותית כזו במצב תנועה או במצב לחצנים, יכול להגדיל את שולי התצוגה באמצעות getInsets(int) עם WindowInsetsCompat.Type.systemBars()

הקוד הבא לדוגמה מראה איך מטמיעים insets של סרגלי מערכת:

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets ->
  val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
  // Apply the insets as a margin to the view. This solution sets
  // only the bottom, left, and right dimensions, but you can apply whichever
  // insets are appropriate to your layout. You can also update the view padding
  // if that's more appropriate.
  v.updateLayoutParams<MarginLayoutParams> {
      leftMargin = insets.left,
      bottomMargin = insets.bottom,
      rightMargin = insets.right,
  }

  // Return CONSUMED if you don't want want the window insets to keep passing
  // down to descendant views.
  WindowInsetsCompat.CONSUMED
}

Java

ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> {
  Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
  // Apply the insets as a margin to the view. This solution sets only the
  // bottom, left, and right dimensions, but you can apply whichever insets are
  // appropriate to your layout. You can also update the view padding if that's
  // more appropriate.
  MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
  mlp.leftMargin = insets.left;
  mlp.bottomMargin = insets.bottom;
  mlp.rightMargin = insets.right;
  v.setLayoutParams(mlp);

  // Return CONSUMED if you don't want want the window insets to keep passing
  // down to descendant views.
    return WindowInsetsCompat.CONSUMED;
});

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

סרגל ניווט שקוף שלא מכסה את ה-FAB
איור 4. פתרון בעיות של חפיפה חזותית בלחצן במצב 'סינון תוכן'.

אותו עיקרון חל על מצב ניווט באמצעות תנועות, כפי שמוצג באיור 5:

מקצה לקצה עם ניווט באמצעות תנועות
איור 5. פתרון בעיות של חפיפה חזותית בתנועה מצב ניווט.

רכיבי מגרעת במסך

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

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

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets ->
  val bars = insets.getInsets(
    WindowInsetsCompat.Type.systemBars()
      or WindowInsetsCompat.Type.displayCutout()
  )
  v.updatePadding(
    left = bars.left,
    top = bars.top,
    right = bars.right,
    bottom = bars.bottom,
  )
  WindowInsetsCompat.CONSUMED
}

Java

ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> {
  Insets bars = insets.getInsets(
    WindowInsetsCompat.Type.systemBars()
    | WindowInsetsCompat.Type.displayCutout()
  );
  v.setPadding(bars.left, bars.top, bars.right, bars.bottom);
  return WindowInsetsCompat.CONSUMED;
});

כדי לקבוע את הערך של WindowInsetsCompat, לוקחים את האו של את סרגלי המערכת ואת סוגי המגרעת במסך.

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

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

inset של תנועות במערכת

inset של תנועות במערכת מייצגות את האזורים בחלון שבהם תנועות מערכת לקבל עדיפות על פני האפליקציה. האזורים הבאים מוצגים בכתום בתרשים 6:

דוגמה לשילוב של תנועות במערכת
איור 6. insets של תנועות במערכת.

בדומה לכניסות הפנימיות של סרגל המערכת, ניתן להימנע מחפיפה של תנועות מובנות במערכת באמצעות getInsets(int) עם WindowInsetsCompat.Type.systemGestures()

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

ב-Android מגרסה 10 ואילך, insets של תנועות במערכת מכילים כניסה תחתונה של תנועה במסך הבית, וכניסת פסקה שמאלה וימינה לתנועות החזרה:

דוגמה למדידות של הטמעת תנועה במערכת
איור 7. מדידות של הטמעת תנועות מערכת.

הקוד הבא לדוגמה מראה איך להטמיע insets של תנועות מערכת:

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets ->
    val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures())
    // Apply the insets as padding to the view. Here, set all the dimensions
    // as appropriate to your layout. You can also update the view's margin if
    // more appropriate.
    view.updatePadding(insets.left, insets.top, insets.right, insets.bottom)

    // Return CONSUMED if you don't want the window insets to keep passing down
    // to descendant views.
    WindowInsetsCompat.CONSUMED
}

Java

ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> {
    Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures());
    // Apply the insets as padding to the view. Here, set all the dimensions
    // as appropriate to your layout. You can also update the view's margin if
    // more appropriate.
    view.setPadding(insets.left, insets.top, insets.right, insets.bottom);

    // Return CONSUMED if you don't want the window insets to keep passing down
    // to descendant views.
    return WindowInsetsCompat.CONSUMED;
});

רכיבי החומר

רכיבי Android Materials המבוססים על תצוגות מפורטות (com.google.android.material){:.external} מטפלת באופן אוטומטי ברכיבי inset, כולל BottomAppBar, BottomNavigationView, NavigationRailView וגם NavigationView

אבל, AppBarLayout לא מטפל באופן אוטומטי בהטמעות. הוסף android:fitsSystemWindows="true" כדי לטפל בכניסות מובילות או להשתמש ב-setOnApplyWindowInsetsListener.

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

מצב אימרסיבי

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

Kotlin

val windowInsetsController =
      WindowCompat.getInsetsController(window, window.decorView)

// Hide the system bars.
windowInsetsController.hide(Type.systemBars())

// Show the system bars.
windowInsetsController.show(Type.systemBars())

Java

Window window = getWindow();
WindowInsetsControllerCompat windowInsetsController =
      WindowCompat.getInsetsController(window, window.getDecorView());
if (windowInsetsController == null) {
    return;
  }
// Hide the system bars.
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars());

// Show the system bars.
windowInsetsController.show(WindowInsetsCompat.Type.systemBars());

מידע נוסף זמין במאמר הסתרת פסי המערכת של מצב עשיר מידע נוסף על הטמעת התכונה הזו.

מקורות מידע נוספים

בהפניות הבאות אפשר לקרוא מידע נוסף על WindowInsets, תנועה ואיך רכיבי inset פועלים: