עד Wear OS 7 (API 37), הפלטפורמה לא הציגה שורת סטטוס של המערכת מעל חלונות האפליקציה – האפליקציות שלטו בכל המסך ויכלו להציג כל תוכן בחלק העליון (השעה 12:00) (למשל שעון TimeText בתוך האפליקציה, כותרות מעוקלות בהתאמה אישית או אמצעי בקרה בחלק העליון).
החל מ-Wear OS 8 – וזמין עכשיו לבדיקה בגרסת טרום-השקה מוקדמת באמולטור של גרסת טרום-השקה בטא של Wear OS 7.1 (API 37.2-beta1) – המערכת מעבדת שורת סטטוס מעל חלונות האפליקציה במיקום של השעה 12:00 כדי להציג את השעה ואת אינדיקטורי הסטטוס. כדי למנוע חפיפה עם שורת הסטטוס של המערכת, האפליקציות צריכות להפסיק להציג שעון משלהן (TimeText) ולכבד את השוליים של החלון של שורת הסטטוס העליונה (מטופל באופן אוטומטי על ידי AppScaffold ו-ScreenScaffold מ-Wear Compose בגרסה 1.8 ואילך), או להסתיר את שורת הסטטוס של המערכת כשנדרשת חוויה סוחפת במסך מלא.
אלה חלק מהיתרונות המרכזיים שלהם:
- עקביות חזותית: משפחת גופנים, מיקום ורקע אחידים לשעון בכל המערכת ובכל האפליקציות.
- אינדיקטורים של סטטוס המערכת: מאפשרים לפלטפורמה להציג סמלי סטטוס (כמו אינדיקטורים של מיקרופון ומיקום פעילים, סטטוס קישוריות או מידע על הסוללה) ואת השעה בממשקים שונים. בכל פעם מוצג רק סמל אחד, לפי סדר העדיפויות.
- תיאום אוטומטי של גלילה ומעבר: כשמשתמשים ב-Jetpack Compose ל-Wear OS בגרסה 1.8, שורת הסטטוס של המערכת מוסתרת באופן אוטומטי כשהמשתמשים גוללים בתוכן, ומופיעה שוב אחרי פרק זמן קצר (שתי שניות) של חוסר פעילות.
הגדרת האפליקציה
כדי להתחיל, צריך לבצע את השלבים הבאים:
- מתקינים את Android Studio Preview (Canary).
- ב-SDK Manager, מורידים את קובץ האימג' של מערכת האמולטור של גרסת טרום-ההשקה של Wear OS 7.1 (API 37.2-beta1). הגרסה הזו מספקת גישה מוקדמת לשורת הסטטוס של מערכת Wear OS 8 לפני Wear OS 8 SDK.
- ב-Device Manager, יוצרים ומפעילים מכשיר וירטואלי של Wear OS באמצעות קובץ האימג' API 37.2-beta1.
כדי לתמוך בשורת הסטטוס של המערכת באפליקציה, צריך לעדכן את גרסת targetSdk של האפליקציה ל-35 ואילך. כדי לשמור על תאימות לדורות קודמים של אפליקציות, הפלטפורמה מפעילה את שורת הסטטוס של המערכת רק באפליקציות שמטרגטות את API 35 ואילך.
בנוסף, מעדכנים את יחסי התלות של Wear Compose לגרסת האלפא העדכנית (כרגע 1.8.0-alpha02), כמו שמוצג בקטע הקוד הבא. אם באפליקציה שלכם מותקנת גרסה ישנה יותר של Wear Compose, אתם יכולים להשתמש במיומנות ההעברה ל-Wear Compose Material 3 כדי להקל על תהליך ההעברה.
android {
defaultConfig {
targetSdk = 35
}
}
dependencies {
implementation("androidx.wear.compose:compose-foundation:1.8.0-alpha02")
implementation("androidx.wear.compose:compose-material3:1.8.0-alpha02")
}
שימוש בשורת הסטטוס של המערכת
בגרסת האלפא האחרונה של Wear Compose Material 3 1.8.0 (כרגע 1.8.0-alpha02), הספרייה מצרפת את האפליקציה באופן אוטומטי על ידי מיזוג המאפיין com.google.wear.ENABLE_GLOBAL_STATUS_BAR <meta-data> עם AndroidManifest.xml. בזמן הריצה, AppScaffold ו-ScreenScaffold בודקים אם שורת הסטטוס של המערכת מופעלת במכשיר ואם המאפיין הזה של הצטרפות למניפסט מוגדר כ-true:
- באמולטור של גרסת טרום-השקה (Preview) או ב-Wear OS 8 ואילך (אם הצטרפתם):
AppScaffoldמבטל אתTimeTextהפנימי שלו, כדי ששורת הסטטוס של המערכת תוצג בצורה נקייה במיקום של השעה 12:00 בלי כפילויות.ScreenScaffoldמחשב מחדש אתcontentPaddingכדי להביא בחשבון את גבולות ההוספה של שורת הסטטוס, ומתאם את ההסתרה וההצגה של שורת הסטטוס בזמן הגלילה ברשימה. - במכשירים עם Wear OS 7 וגרסאות קודמות (או כשלא מצטרפים):
AppScaffoldחוזר אוטומטית לעיבוד שלTimeTextהרגיל בתוך האפליקציה, ושומר על תאימות לדורות קודמים מבסיס קוד יחיד.
@Composable
fun GsbSampleApp() {
// AppScaffold coordinates the system status bar across the app
// and falls back to rendering TimeText on Wear OS 7 and earlier.
AppScaffold {
val columnState = rememberTransformingLazyColumnState()
// ScreenScaffold includes status bar top inset clearance in
// contentPadding and hides/shows the status bar during list scrolling.
ScreenScaffold(scrollState = columnState) { contentPadding ->
TransformingLazyColumn(
state = columnState,
contentPadding = contentPadding,
) {
item {
ListHeader { Text("Hello Status Bar") }
}
items(count = 15) { index ->
Button(onClick = { /* Handle click */ }) {
Text("Item #${index + 1}")
}
}
}
}
}
}
זה מה שצפוי לקרות כשמריצים את הקוד לדוגמה:
- במצב מנוחה (בראש הרשימה): שורת הסטטוס של המערכת מוצגת במיקום של השעה 12:00. הכותרת "Hello Status Bar" נמצאת מתחת לאזור הפנימי של שורת הסטטוס, בלי חיתוך או חפיפה.
- גלילה למטה: כשגוללים בין הפריטים ברשימה, שורת הסטטוס מוסתרת והפריטים ברשימה נגללים מקצה לקצה מאחורי המסגרת העליונה.
- במצב חוסר פעילות: כשמפסיקים לגלול ומשחררים את המסך, שורת הסטטוס מופיעה שוב באופן אוטומטי אחרי כ-2 שניות.
טיפול בתרחישים נפוצים ובהתאמות אישיות
בקטעים הבאים מוסבר איך לטפל בתרחישים נפוצים שבהם אתם עשויים להיתקל כשאתם עובדים עם שורת הסטטוס של המערכת.
טיפול במסכים ללא גלילה (סטטיים)
במסכים שמשתמשים בפריסה סטטית (כמו Column או Box) במקום ברשימה שניתן לגלול, צריך להחיל את contentPadding שסופק על ידי ScreenScaffold על פריסת הבסיס כדי שרכיבי ממשק המשתמש העליונים לא יחפפו לשורת הסטטוס של המערכת:
AppScaffold {
ScreenScaffold { contentPadding ->
Column(modifier = Modifier.padding(contentPadding)) {
Text("Static Screen Content")
}
}
}
עבודה עם רכיבים אינטראקטיביים במסך מלא
רכיבים אינטראקטיביים במסך מלא ב-Wear Compose Material 3 – כולל AlertDialog, Dialog, Stepper, TimePicker ו-DatePicker – מסתירים באופן אוטומטי את שורת הסטטוס של המערכת כשהם מוצגים במסך, כדי שלפקדים שלהם תהיה גישה מלאה לחלק העליון של התצוגה המעגלית. כשסוגרים את המודעה, שורת הסטטוס של המערכת משוחזרת באופן אוטומטי באמצעות ה-API של בקר ה-WindowInsets.
מעבר למצב אימרסיבי
כדי לעבור למצב אימרסיבי – שבו גם שורת הסטטוס של המערכת וגם TimeText המקומי מוסתרים – מוסיפים את הרכיב הניתן לשילוב StatusBarSuppression לאפליקציה או למסך. שמרו את המצב האימרסיבי למסכים שהמשתמש רואה לזמן קצר (שכבות-על של אישור, תיבות דו-שיח) או למסכים שמשתמשים בכל התצוגה (אינדיקטורים של התקדמות במסך מלא).
מתי כדאי להשתמש במצב אימרסיבי ברמת המסך
אם רק מסך ספציפי באפליקציה צריך להיות במסך מלא או במצב אימרסיבי, צריך להפעיל את StatusBarSuppression() בתוך התוכן של ScreenScaffold.
ScreenScaffold מסתיר באופן אוטומטי את שורת הסטטוס של המערכת (ומשמיט את המרווח הפנימי של שורת הסטטוס העליונה) כשהמסך הזה פעיל, ואז משחזר את שורת הסטטוס של המערכת כשמנווטים חזרה למסכים אחרים:
AppScaffold {
ScreenScaffold() {
StatusBarSuppression()
// Full-screen immersive content
}
}
מתי כדאי להשתמש במצב אימרסיבי ברמת האפליקציה
אם כל האפליקציה (או Activity) היא חוויה סוחפת במסך מלא בכל המסכים, צריך להשתמש ב-StatusBarSuppression ברמת AppScaffold ולעטוף את התוכן כדי להסתיר את שורת הסטטוס של המערכת בכל המסכים:
// Use StatusBarSuppression at AppScaffold level and wrap your content
// to suppress status bar in the entire scaffold.
AppScaffold {
StatusBarSuppression {
SwipeDismissableNavHost(...) {
// Nested screens inherit suppression and 0.dp padding
}
}
}
הצגת שינויים מותאמים אישית בטקסט של השעה
אם אתם צריכים להציג כותרת מעוקלת בהתאמה אישית או להשבית באופן זמני את שורת הסטטוס של המערכת במסך ספציפי או בכל האפליקציה במהלך המעבר ל-Wear OS 8, העברת timeText בהתאמה אישית תסתיר את שורת הסטטוס של המערכת:
// Screen-level custom TimeText override:
ScreenScaffold(
timeText = { TimeText { timeTextCurvedText("Custom Status") } },
) {
// Content
}
// App-level opt-out using in-app TimeText:
AppScaffold(
timeText = { TimeText() },
) {
// Screens
}
הטמעה באמצעות תצוגות מפורטות (לא מומלץ)
אם האפליקציה משתמשת בתצוגות של Android במקום ב-Jetpack Compose ל-Wear OS, צריך להביע הסכמה באמצעות AndroidManifest.xml. בניגוד לגרסת האלפא האחרונה של Wear Compose Material 3, שבה שורת הסטטוס של המערכת מופעלת באופן אוטומטי, באפליקציות שמבוססות על תצוגה צריך להביע הסכמה באופן מפורש על ידי הוספת התג ENABLE_GLOBAL_STATUS_BAR <meta-data> בתוך <application>:
<application ...>
<meta-data
android:name="com.google.wear.ENABLE_GLOBAL_STATUS_BAR"
android:value="true" />
</application>
מעקב אחרי הוספות לחלון העליון
משתמשים ב-ViewCompat.setOnApplyWindowInsetsListener ובודקים את הערך של windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()). כאשר
statusBarInsets.top > 0, הסירו את ממשק המשתמש הקודם של השעה 12:00 והתאימו את המרווח הפנימי העליון. אחרת, חזרו לממשק המשתמש הקודם:
ViewCompat.setOnApplyWindowInsetsListener(rootView) { view, windowInsets ->
val statusBarInsets = windowInsets.getInsets(
WindowInsetsCompat.Type.statusBars()
)
if (statusBarInsets.top > 0) {
// status bar is visible: remove legacy 12 o'clock UI and apply top inset padding
view.updatePadding(top = statusBarInsets.top)
} else {
// status bar is not visible: fall back to legacy UI and padding
}
WindowInsetsCompat.CONSUMED
}
הסתרה והצגה של שורת הסטטוס באופן פרוגרמטי
בניגוד ל-ScreenScaffold ב-Compose, באפליקציות שמבוססות על תצוגה צריך להסתיר או להציג באופן מפורש את שורת הסטטוס של המערכת (לדוגמה, כשנכנסים לתצוגה מקיפה במסך מלא או כשמתאמים את התנהגות הגלילה) באמצעות WindowInsetsControllerCompat:
val insetsController = WindowCompat.getInsetsController(window, window.decorView)
// Hide the status bar
insetsController.hide(WindowInsetsCompat.Type.statusBars())
// Show the status bar
insetsController.show(WindowInsetsCompat.Type.statusBars())
בדיקת האפליקציה
כשבודקים את האפליקציה באמולטור של גרסת טרום-ההשקה (Preview) של Wear OS 7.1 בטא (API 37.2-beta1), צריך לבדוק את הדברים הבאים:
- השעון מופיע רק פעם אחת: מוודאים שרק השעה בשורת הסטטוס של המערכת מופיעה בשעה 12:00, ושאין חפיפה עם
TimeTextמדור קודם בתוך האפליקציה ועם תוכן האפליקציה. - מרווח פנימי עליון: מוודאים שכותרות המסך, הכותרות העליונות והכפתורים העליונים מופיעים מתחת לשורת הסטטוס.
- שכבות-על ותיבות דו-שיח במסך מלא: ודאו שתיבות דו-שיח, בוררים, פקדי שלבים ופעילויות מותאמות אישית במסך מלא מסתירים את שורת הסטטוס כשהם נפתחים, ומשחזרים אותה כשהם נסגרים.