Do wersji Wear OS 7 (API 37) platforma nie renderowała systemowego paska stanu nad oknami aplikacji – aplikacje zajmowały cały ekran i mogły wyświetlać dowolne treści u góry (na godzinie 12), np. zegar w aplikacji TimeText, niestandardowe zakrzywione nagłówki lub górne elementy sterujące.
Począwszy od Wear OS 8 (funkcja jest już dostępna do testowania we wczesnej wersji przedpremierowej w emulatorze Wear OS 7.1 Beta Preview (API 37.2-beta1)), system renderuje pasek stanu nad oknami aplikacji na godzinie 12, aby wyświetlać godzinę i wskaźniki stanu. Aby uniknąć nakładania się na pasek stanu systemu, aplikacje powinny przestać renderować własny zegar (TimeText) i uwzględniać wstawki okna górnego paska stanu (obsługiwane automatycznie przez AppScaffold i ScreenScaffold od wersji Wear Compose 1.8) lub ukrywać pasek stanu systemu, gdy potrzebny jest tryb pełnoekranowy.
Najważniejsze korzyści:
- Spójność wizualna: jednolita typografia, umiejscowienie i tło zegara w całym systemie i we wszystkich aplikacjach.
- Wskaźniki stanu systemu: umożliwia platformie wyświetlanie ikon stanu (takich jak wskaźniki aktywnego mikrofonu i lokalizacji, stan połączenia czy informacje o baterii) oraz czasu na różnych platformach. W danym momencie wyświetlana jest tylko jedna ikona, zgodnie z priorytetem.
- Automatyczne przewijanie i koordynacja przejść: po sparowaniu z Jetpack Compose na Wear OS 1.8 systemowy pasek stanu automatycznie ukrywa się, gdy użytkownicy przewijają treści, i pojawia się ponownie po krótkiej (2 s) przerwie.
Konfigurowanie aplikacji
Aby rozpocząć, wykonaj te czynności:
- Zainstaluj Android Studio Preview (Canary).
- W SDK Manager pobierz obraz systemu emulatora Wear OS 7.1 w wersji testowej (API 37.2-beta1). Ta wersja zapewnia wcześniejszy dostęp do paska stanu systemu Wear OS 8 przed udostępnieniem pakietu SDK Wear OS 8.
- W Menedżerze urządzeń utwórz i uruchom urządzenie wirtualne z Wear OS, używając obrazu API 37.2-beta1.
Aby obsługiwać pasek stanu systemu w aplikacji, zaktualizuj jej wersję targetSdk do 35 lub nowszej. Platforma aktywuje pasek stanu systemu tylko w przypadku aplikacji kierowanych na interfejs API 35 lub nowszy, aby zachować zgodność wsteczną ze starszymi aplikacjami.
Zaktualizuj też zależności Wear Compose do najnowszej wersji alfa (obecnie 1.8.0-alpha02), jak pokazano w tym fragmencie kodu. Jeśli Twoja aplikacja używa starszej wersji Wear Compose, możesz skorzystać z umiejętności migracji do Wear Compose Material 3, aby ułatwić migrację.
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")
}
Korzystanie z paska stanu systemu
W najnowszej wersji alfa Wear Compose Material 3 1.8.0 (obecnie 1.8.0-alpha02) biblioteka automatycznie włącza aplikację, scalając właściwość com.google.wear.ENABLE_GLOBAL_STATUS_BAR <meta-data> z AndroidManifest.xml. W czasie działania AppScaffold i ScreenScaffold sprawdzają, czy pasek stanu systemu jest włączony na urządzeniu i czy ta właściwość akceptacji w pliku manifestu jest ustawiona na true:
- W emulatorze wersji testowej / Wear OS 8 lub nowszym (po wyrażeniu zgody):
AppScaffoldukrywa wewnętrzny elementTimeText, dzięki czemu pasek stanu systemu jest wyświetlany na godzinie 12 bez duplikowania.ScreenScaffoldponownie obliczacontentPadding, aby uwzględnić granice wstawki paska stanu, i koordynuje ukrywanie i wyświetlanie paska stanu podczas przewijania listy. - Na urządzeniach z Wear OS 7 i starszych (lub gdy nie wyrażono zgody):
AppScaffoldautomatycznie powraca do renderowania standardowej funkcjiTimeTextw aplikacji, zachowując pełną zgodność wsteczną z jednej bazy kodu.
@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}")
}
}
}
}
}
}
Oto czego możesz się spodziewać podczas uruchamiania przykładu:
- W stanie spoczynku (góra listy): pasek stanu systemu jest wyświetlany na godzinie 12. Nagłówek „Hello Status Bar” znajduje się pod obszarem wstawki paska stanu i nie jest przycięty ani nie nakłada się na inne elementy.
- Przewijanie w dół: gdy przewijasz elementy listy, pasek stanu jest ukrywany, a elementy listy są przewijane od krawędzi do krawędzi za górną ramką.
- Bezczynność: gdy przestaniesz przewijać i puścisz ekran, pasek stanu automatycznie pojawi się ponownie po około 2 sekundach.
Obsługa typowych scenariuszy i dostosowań
W sekcjach poniżej opisano, jak postępować w typowych sytuacjach, które mogą wystąpić podczas pracy z paskiem stanu systemu.
Obsługa ekranów bez przewijania (statycznych)
Na ekranach, które używają układu statycznego (takiego jak Column lub Box), a nie przewijanej listy, zastosuj contentPadding dostarczany przez ScreenScaffold do układu głównego, aby górne elementy interfejsu nie nakładały się na pasek stanu systemu:
AppScaffold {
ScreenScaffold { contentPadding ->
Column(modifier = Modifier.padding(contentPadding)) {
Text("Static Screen Content")
}
}
}
Praca z interaktywnymi komponentami pełnoekranowymi
Pełnoekranowe komponenty interaktywne w Wear Compose Material 3 – w tym AlertDialog, Dialog, Stepper, TimePicker i DatePicker – automatycznie ukrywają pasek stanu systemu, gdy są wyświetlane na ekranie, dzięki czemu ich elementy sterujące mają pełny dostęp do górnej części okrągłego wyświetlacza. Po zamknięciu pasek stanu systemu jest automatycznie przywracany za pomocą interfejsu API kontrolera wstawek okna.
Przełączanie na tryb imersji
Aby przełączyć się na tryb imersji, w którym ukryty jest zarówno pasek stanu systemu, jak i lokalny element TimeText, dodaj do aplikacji lub ekranu element kompozycyjny StatusBarSuppression. Tryb imersji należy zarezerwować dla ekranów, które użytkownik widzi przez krótki czas (nakładki z potwierdzeniem, okna dialogowe) lub które zajmują cały wyświetlacz (pełnoekranowe wskaźniki postępu).
Kiedy używać trybu pojemnego na poziomie ekranu
Jeśli tylko określony ekran w aplikacji ma być wyświetlany w trybie pełnoekranowym lub immersyjnym, wywołaj StatusBarSuppression() w treści ScreenScaffold.
ScreenScaffold automatycznie ukrywa pasek stanu systemu (i pomija górne dopełnienie paska stanu), gdy ten ekran jest aktywny, a następnie przywraca pasek stanu systemu po powrocie do innych ekranów:
AppScaffold {
ScreenScaffold() {
StatusBarSuppression()
// Full-screen immersive content
}
}
Kiedy używać trybu imersji na poziomie aplikacji
Jeśli cała aplikacja (lub Activity) jest wyświetlana na wszystkich ekranach w trybie pełnoekranowym, użyj StatusBarSuppression na poziomie AppScaffold i opakuj zawartość, aby ukryć pasek stanu systemu na wszystkich ekranach:
// 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
}
}
}
Wyświetlanie niestandardowych zastąpień tekstu czasu
Jeśli podczas migracji na Wear OS 8 musisz wyświetlić niestandardowy zakrzywiony nagłówek lub tymczasowo zrezygnować z systemowego paska stanu na konkretnym ekranie lub w całej aplikacji, przekazanie niestandardowego elementu kompozycyjnego timeText spowoduje ukrycie systemowego paska stanu:
// Screen-level custom TimeText override:
ScreenScaffold(
timeText = { TimeText { timeTextCurvedText("Custom Status") } },
) {
// Content
}
// App-level opt-out using in-app TimeText:
AppScaffold(
timeText = { TimeText() },
) {
// Screens
}
Implementacja za pomocą widoków (niezalecana)
Jeśli aplikacja używa widoków Androida, a nie Jetpack Compose na Wear OS, włącz tę funkcję za pomocą AndroidManifest.xml. W przeciwieństwie do najnowszej wersji alfa Wear Compose Material 3, która automatycznie włącza systemowy pasek stanu, aplikacje oparte na widokach muszą wyraźnie wyrazić zgodę na korzystanie z tej funkcji, dodając tag ENABLE_GLOBAL_STATUS_BAR <meta-data> w pliku <application>:
<application ...>
<meta-data
android:name="com.google.wear.ENABLE_GLOBAL_STATUS_BAR"
android:value="true" />
</application>
Monitorowanie wstawek w górnym oknie
Użyj ViewCompat.setOnApplyWindowInsetsListener i sprawdź wartość windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()). Jeśli statusBarInsets.top > 0, usuń starszy interfejs na godzinie 12 i dostosuj górne dopełnienie. W przeciwnym razie wróć do starszego interfejsu:
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
}
Ukrywanie i wyświetlanie paska stanu za pomocą kodu
W przeciwieństwie do ScreenScaffold w Compose aplikacje oparte na widoku muszą wyraźnie ukrywać lub wyświetlać pasek stanu systemu (np. podczas przechodzenia do pełnoekranowego widoku immersyjnego lub koordynowania zachowania przewijania) za pomocą 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())
Testowanie aplikacji
Podczas testowania aplikacji w emulatorze Wear OS 7.1 w wersji testowej beta (API 37.2-beta1) sprawdź te kwestie:
- Zegar pojawia się tylko raz: sprawdź, czy na godzinie 12 pojawia się tylko godzina z paska stanu systemu i czy nie nakłada się na nią żaden starszy element
TimeTextw aplikacji ani żadna treść aplikacji. - Górne dopełnienie: sprawdź, czy tytuły ekranów, nagłówki i górne przyciski wyświetlają się pod paskiem stanu.
- Nakładki i okna pełnoekranowe: sprawdź, czy okna, selektory, kroki i niestandardowe działania pełnoekranowe ukrywają pasek stanu po otwarciu i przywracają go po zamknięciu.