Tryb okien na pulpicie umożliwia użytkownikom uruchamianie wielu aplikacji jednocześnie w oknach aplikacji o zmienianym rozmiarze, co zapewnia wszechstronność i wygodę podobną do korzystania z komputera.
Na ilustracji 1 widać organizację ekranu z włączonym trybem okien na pulpicie. Warto wiedzieć:
- Użytkownicy mogą uruchamiać kilka aplikacji obok siebie jednocześnie.
- Pasek aplikacji jest umieszczony na stałe u dołu wyświetlacza i pokazuje uruchomione aplikacje. Użytkownicy mogą przypinać aplikacje, aby mieć do nich szybki dostęp.
- Nowy, konfigurowalny pasek nagłówka zdobi górę każdego okna i zawiera elementy sterujące, takie jak minimalizowanie i maksymalizowanie.
Domyślnie aplikacje na tabletach z Androidem otwierają się na pełnym ekranie. Aby uruchomić aplikację w trybie okien na pulpicie, naciśnij i przytrzymaj uchwyt okna u góry ekranu, a następnie przeciągnij go w interfejsie, jak pokazano na rysunku 2.
Gdy aplikacja jest otwarta w trybie okien na pulpicie, inne aplikacje również otwierają się w oknach na pulpicie.
Użytkownicy mogą też wywołać tryb okien na pulpicie z menu, które pojawia się pod uchwytem okna po kliknięciu lub dotknięciu uchwytu, albo za pomocą skrótu klawiszowego klawisz Meta (Windows, Command lub Wyszukaj) + Ctrl + strzałka w dół.
Użytkownicy mogą wyjść z trybu okien na pulpicie, zamykając wszystkie aktywne okna lub chwytając uchwyt okna u góry okna i przeciągając aplikację na górę ekranu. Skrót klawiszowy Meta + H również zamyka okna na pulpicie i ponownie uruchamia aplikacje w trybie pełnoekranowym.
Aby wrócić do trybu okien na pulpicie, na ekranie Ostatnie kliknij lub wybierz kafelek przestrzeni na komputerze.
Zmiana rozmiaru i tryb zgodności
W trybie okien na pulpicie aplikacje z zablokowaną orientacją można dowolnie zmieniać. Oznacza to, że nawet jeśli aktywność jest zablokowana w orientacji pionowej, użytkownicy mogą nadal zmieniać rozmiar aplikacji na okno w orientacji poziomej.
Aplikacje zadeklarowane jako niemożliwe do zmiany rozmiaru (czyli resizeableActivity = false) mają interfejs skalowany przy zachowaniu tego samego współczynnika proporcji.
Aplikacje aparatu, które blokują orientację lub są zadeklarowane jako niemożliwe do zmiany rozmiaru, mają specjalne traktowanie wizjerów: okno można w pełni zmieniać, ale wizjer zachowuje ten sam format obrazu. Zakładając, że aplikacje zawsze działają w orientacji pionowej lub poziomej, programiści na stałe kodują lub w inny sposób przyjmują założenia, które prowadzą do błędnych obliczeń orientacji lub proporcji podglądu lub przechwyconego obrazu, co skutkuje rozciągniętymi, odwróconymi lub obróconymi obrazami.
Dopóki aplikacje nie będą w pełni obsługiwać responsywnych wizjerów aparatu, specjalne traktowanie zapewni bardziej podstawową obsługę, która ograniczy skutki błędnych założeń.
Więcej informacji o trybie zgodności w przypadku aplikacji aparatu znajdziesz w artykule Tryb zgodności urządzenia.
Dostosowywane wcięcia nagłówka
Wszystkie aplikacje działające w trybie okien na pulpicie mają pasek nagłówka, nawet w trybie pełnoekranowym. Możesz dostosować ten pasek, aby zapobiec zasłanianiu zawartości aplikacji i wyświetlać niestandardowe elementy interfejsu bezpośrednio w przestrzeni nagłówka.
Implementacja
Aby narysować niestandardową treść na pasku nagłówka, najpierw ustaw tło paska nagłówka jako przezroczyste. Możesz to zrobić za pomocą flagi APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND z parametrem WindowInsetsController.
window.insetsController?.setSystemBarsAppearance( WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND, WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND )
Gdy pasek nagłówka będzie przezroczysty, możesz dostosować obszar nagłówka do wyglądu aplikacji. Użyj WindowInsets.isCaptionBarVisible, aby wykryć, czy pasek jest obecny, i zastosować odpowiednią wysokość lub dopełnienie w układzie.
@OptIn(ExperimentalLayoutApi::class) @Composable fun CaptionBar() { if (WindowInsets.isCaptionBarVisible) { Row( modifier = Modifier .windowInsetsTopHeight(WindowInsets.captionBar) .fillMaxWidth() .background(if (isSystemInDarkTheme()) Color.White else Color.Black), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ) { Text( text = "Caption Bar Title", style = MaterialTheme.typography.titleMedium, modifier = Modifier.padding(4.dp) ) } } }
setSystemBarsAppearance(appearance,mask): konfiguruje styl wizualny pasków systemowych. Pierwszy parametr określa flagi docelowego wyglądu, a drugi działa jako maska, która kontroluje, które konkretne flagi są modyfikowane.windowInsetsTopHeight(): automatycznie ustawia wysokość elementu kompozycyjnego tak, aby pasowała do paska nagłówka systemu. Dzięki temu niestandardowe tło wypełnia obszar podpisu bez kodowania na stałe wartości pikseli.WindowInsets.captionBar: podaje wymiary elementów sterujących okien na pulpicie (Zamknij, Maksymalizuj itp.), dzięki czemu interfejs użytkownika może automatycznie skalować się lub ukrywać po włączeniu lub wyłączeniu trybu okien na pulpicie.
Więcej informacji znajdziesz w artykule Informacje o wcięciach w oknie. Oprócz tytułu na pasku podpisu możesz wyświetlać inne elementy interfejsu, takie jak karty (jak w Google Chrome), paski wyszukiwania czy awatary profilu.
Interfejs użytkownika
Aby uniknąć nakładania się interfejsu na przyciski systemowe, Android 15 udostępnia metodę WindowInsets#getBoundingRects(). Metoda zwraca listę obiektów Rect reprezentujących obszary zajmowane przez elementy systemu. Pozostała przestrzeń na pasku podpisu to strefa bezpieczna, w której możesz bezpiecznie umieszczać niestandardowe treści.
Przełączaj wygląd elementów napisów systemowych w przypadku motywu jasnego i ciemnego za pomocą elementu APPEARANCE_LIGHT_CAPTION_BARS. Dostęp do wstawek uzyskasz, wpisując WindowInsets.Companion.captionBar() w trybie tworzenia lub WindowInsets.Type.captionBar() w widokach.
Więcej informacji znajdziesz w artykule Informacje o wcięciach w oknie.
Wielozadaniowość i obsługa wielu instancji
Wielozadaniowość jest podstawą trybu okien na pulpicie, a umożliwienie korzystania z wielu instancji aplikacji może znacznie zwiększyć produktywność użytkowników.
Od Androida 15 możesz używać PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI. Ustawiając tę właściwość w AndroidManifest.xml, określasz, że interfejs systemu powinien udostępniać opcje (np. przycisk „Nowe okno”) umożliwiające uruchamianie aplikacji w wielu instancjach.
<application>
<property
android:name="android.window.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI"
android:value="true" />
</application>
Uwaga: w trybie wielu okien i innych środowiskach z wieloma oknami, np. w trybie okien na pulpicie, nowe zadania otwierają się w nowym oknie. Dlatego za każdym razem, gdy aplikacja uruchamia wiele zadań, dokładnie sprawdzaj ścieżkę użytkownika.
Zarządzanie instancjami aplikacji za pomocą gestów przeciągania
W trybie wielu okien użytkownicy mogą uruchamiać nową instancję aplikacji, przeciągając element interfejsu (np. kartę lub dokument) z okna aplikacji. Użytkownicy mogą też przenosić elementy między różnymi instancjami tej samej aplikacji.
Przenoszenie danych metodą „przeciągnij i upuść”
Aby skonfigurować komponent jako źródło przeciągania w przypadku przeciągania i upuszczania w trybie podzielonym, co umożliwia użytkownikom przeciąganie treści do innej instancji aplikacji lub tworzenie nowej instancji przez upuszczanie treści w pustym obszarze ekranu, użyj modyfikatora dragAndDropSource. W funkcji lambda zwróć DragAndDropTransferData, przekazując ClipData zawierający dane do przeniesienia oraz flagi konfigurujące działanie w trybie podzielonym.
Android 15 wprowadza 2 kluczowe flagi dotyczące trybu okien na pulpicie i interakcji z wieloma instancjami:
DRAG_FLAG_GLOBAL_SAME_APPLICATION: wskazuje, że operacja przeciągania może przekraczać granice okien (w przypadku wielu instancji tej samej aplikacji). Gdy funkcjastartDragAndDrop()jest wywoływana z ustawioną tą flagą, tylko widoczne okna należące do tej samej aplikacji mogą uczestniczyć w operacji przeciągania i otrzymywać przeciąganą zawartość.
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( clipData = ClipData.newPlainText("label", "Your data"), flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION ) }
DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG: umożliwia użytkownikom rozpoczęcie nowej instancji aplikacji przez upuszczenie przeciągniętych treści w pustym obszarze ekranu, jeśli żadne inne okno nie obsługuje upuszczania.- Jeśli używasz tej flagi, musisz podać
IntentSenderza pomocąClipData.Item.Builder#setIntentSender(), którego system używa do uruchomienia nowej aktywności w przypadku nieobsłużonego przerwania.
- Jeśli używasz tej flagi, musisz podać
Modifier.dragAndDropSource { _ -> val intent = Intent.makeMainActivity(activity.componentName).apply { putExtra("EXTRA_ITEM_ID", itemId) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK or Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT } val pendingIntent = PendingIntent.getActivity( activity, 0, intent, PendingIntent.FLAG_IMMUTABLE ) val data = ClipData( "Item $itemId", arrayOf(ClipDescription.MIMETYPE_TEXT_INTENT), ClipData.Item.Builder().setIntentSender(pendingIntent.intentSender).build() ) DragAndDropTransferData( clipData = data, flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION or View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG, ) }
Odbieranie przeniesionych danych
Aby zaakceptować dane z innej instancji, użyj modyfikatora dragAndDropTarget.
Jeśli dane pochodzą z innej instancji lub aplikacji, musisz wyraźnie poprosić o uprawnienia.
Modifier.dragAndDropTarget( shouldStartDragAndDrop = { event -> event.toAndroidDragEvent().clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN) }, target = object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { requestDragAndDropPermissions(activity, event.toAndroidDragEvent()) val clipData = event.toAndroidDragEvent().clipData val item = clipData?.getItemAt(0)?.text if (item != null) { // Process the dropped text item here } return item != null } } )
Najważniejsze kroki:
- Filtr: użyj
shouldStartDragAndDrop, aby sprawdzić, czy dane przychodzące (typ MIME) są obsługiwane. - Uprawnienia: wywołaj
requestDragAndDropPermissions(event), aby uzyskać dostęp do danych. - Obsługa: wyodrębnij dane w wywołaniu zwrotnym
onDrop.
Dodatkowe optymalizacje
Dostosuj uruchamianie aplikacji i przełączaj je z trybu okien na pulpicie na pełny ekran.
Określanie domyślnego rozmiaru i położenia
Nie wszystkie aplikacje, nawet te, których rozmiar można zmieniać, potrzebują dużego okna, aby oferować użytkownikom wartość. Możesz użyć metody ActivityOptions#setLaunchBounds(), aby określić domyślny rozmiar i pozycję podczas uruchamiania aktywności.
Włączanie trybu pełnoekranowego z przestrzeni na pulpicie
Aplikacje mogą przejść w tryb pełnoekranowy, wywołując funkcję Activity#requestFullScreenMode(). Ta metoda wyświetla aplikację na pełnym ekranie bezpośrednio z trybu okien na pulpicie.