Mit dem Desktop-Freiform-Fenster können Nutzer mehrere Apps gleichzeitig in App-Fenstern mit anpassbarer Größe ausführen. So erhalten sie ein vielseitiges, desktopähnliches Erlebnis.
Abbildung 1 zeigt die Organisation des Bildschirms, wenn die Desktop-Fensterfunktion aktiviert ist. Hinweise:
- Nutzer können mehrere Apps gleichzeitig nebeneinander ausführen.
- Die Taskleiste befindet sich in einer festen Position unten auf dem Display und zeigt die aktiven Apps an. Nutzer können Apps für den Schnellzugriff anpinnen.
- Die neue anpassbare Kopfzeile oben in jedem Fenster enthält Steuerelemente wie „Minimieren“ und „Maximieren“.
Apps werden auf Android-Tablets standardmäßig im Vollbildmodus geöffnet. Wenn Sie eine App im Desktop-Fenstermodus starten möchten, halten Sie den Fensterziehpunkt oben auf dem Bildschirm gedrückt und ziehen Sie ihn in der Benutzeroberfläche, wie in Abbildung 2 dargestellt.
Wenn eine App in einem Desktop-Freiform-Fenster geöffnet ist, werden auch andere Apps in Desktop-Fenstern geöffnet.
Nutzer können die Desktop-Fensterverwaltung auch über das Menü aufrufen, das unter dem Fenster-Handle angezeigt wird, wenn sie auf das Handle tippen oder klicken oder die Tastenkombination Meta-Taste (Windows, Befehl oder Suche) + Strg + Nach unten verwenden.
Nutzer beenden die Desktop-Fensterdarstellung, indem sie alle aktiven Fenster schließen oder den Fensterziehpunkt oben in einem Desktop-Fenster ziehen und die App an den oberen Bildschirmrand ziehen. Mit der Tastenkombination Meta + H wird der Desktop-Freiform-Fenstermodus ebenfalls beendet und Apps werden wieder im Vollbildmodus ausgeführt.
Wenn Sie zur Desktop-Fensterdarstellung zurückkehren möchten, tippen oder klicken Sie auf dem Bildschirm „Letzte“ auf die Kachel für den Desktop-Arbeitsbereich.
Größenanpassung und Kompatibilitätsmodus
Bei der Desktop-Fensterdarstellung können Apps mit gesperrter Ausrichtung frei in der Größe angepasst werden. Das bedeutet, dass Nutzer die App auch dann in ein Fenster im Querformat umwandeln können, wenn eine Aktivität auf das Hochformat beschränkt ist.
Bei Apps, die als nicht anpassbar deklariert wurden (d. h. resizeableActivity = false), wird die Benutzeroberfläche skaliert, wobei das Seitenverhältnis beibehalten wird.
Kamera-Apps, die die Ausrichtung sperren oder als nicht anpassbar deklariert werden, werden für ihre Kamerasucher speziell behandelt: Das Fenster ist vollständig anpassbar, aber der Sucher behält das gleiche Seitenverhältnis bei. Wenn Apps immer im Hoch- oder Querformat ausgeführt werden, werden in den Apps Annahmen hartcodiert oder anderweitig getroffen, die zu Fehlberechnungen der Ausrichtung oder des Seitenverhältnisses der Vorschau oder des aufgenommenen Bildes führen. Das Ergebnis sind gestreckte, seitlich oder auf dem Kopf stehende Bilder.
Bis Apps bereit sind, vollständig reaktionsfähige Kamerasuchfelder zu implementieren, bietet die Sonderbehandlung eine einfachere Nutzererfahrung, die die Auswirkungen falscher Annahmen abmildert.
Weitere Informationen zum Kompatibilitätsmodus für Kamera-Apps finden Sie unter Gerätekompatibilitätsmodus.
Anpassbare Header-Insets
Alle Apps, die in Desktop-Fenstern ausgeführt werden, haben eine Kopfzeile, auch im Immersive Mode.
Prüfen Sie, ob die Inhalte Ihrer App durch die Kopfzeile verdeckt werden.
Die Kopfzeile ist eine eingebettete Untertitelzeile:
WindowInsets.Companion.captionBar();
in Ansichten WindowInsets.Type.captionBar()>,
die Teil der Systemleisten ist.
Weitere Informationen zum Umgang mit Insets finden Sie unter Inhalte in Ihrer App von Kante zu Kante anzeigen und Fenster-Insets in Compose verarbeiten.
Auch die Kopfzeile lässt sich anpassen. In Android 15 wurde der Darstellungstyp
APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND eingeführt, um die Kopfzeile transparent zu machen, damit Apps benutzerdefinierte Inhalte in der Kopfzeile darstellen können.
Apps sind dann dafür verantwortlich, den oberen Teil ihrer Inhalte so zu gestalten, dass er wie die Titelleiste aussieht (Hintergrund, benutzerdefinierte Inhalte usw.). Die System-Titelleistenelemente (Schließen- und Maximieren-Schaltflächen) werden jedoch vom System in der transparenten Titelleiste über der App gezeichnet.
Apps können das Erscheinungsbild der Systemelemente in der Beschriftung für helle und dunkle Designs mit APPEARANCE_LIGHT_CAPTION_BARS umschalten, ähnlich wie die Statusleiste und die Navigationsleiste.
In Android 15 wurde auch die Methode WindowInsets#getBoundingRects() eingeführt, mit der Apps die Insets der Untertitel-Leiste genauer untersuchen können. Apps können zwischen Bereichen unterscheiden, in denen das System Systemelemente zeichnet, und nicht genutzten Bereichen, in denen Apps benutzerdefinierte Inhalte platzieren können, ohne Systemelemente zu überlappen.
Die von der API zurückgegebene Liste der Rect-Objekte gibt Systemregionen an, die vermieden werden sollten. Im verbleibenden Bereich (berechnet durch Subtrahieren der Rechtecke von den Insets der Untertitelzeile) kann die App Inhalte rendern, ohne Systemelemente zu überlappen, und Eingaben empfangen.
Wenn Sie Ausschlussrechtecke für Systemgesten für einen benutzerdefinierten Header festlegen möchten, implementieren Sie Folgendes in Ihrer Ansicht oder Composable:
// In a custom View's onLayout or a similar lifecycle method
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
if (changed) {
// Calculate the height of your custom header
val customHeaderHeight = 100 // Replace with your actual header height in pixels
// Create a Rect covering your custom header area
val exclusionRect = Rect(0, 0, width, customHeaderHeight)
// Set the exclusion rects for the system
systemGestureExclusionRects = listOf(exclusionRect)
}
}
Multitasking und Unterstützung mehrerer Instanzen
Multitasking ist das Herzstück des Desktop-Freiform-Fensters. Wenn Sie mehrere Instanzen Ihrer App zulassen, kann die Produktivität der Nutzer erheblich gesteigert werden.
In Android 15 wird PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI eingeführt. Apps können diesen Wert festlegen, um anzugeben, dass die System-UI für die App angezeigt werden soll, damit sie als mehrere Instanzen gestartet werden kann.
Sie können PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI in der AndroidManifest.xml Ihrer App innerhalb des <activity>-Tags deklarieren:
<activity
android:name=".MyActivity"
android:exported="true"
android:resizeableActivity="true">
<meta-data
android:name="android.window.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI"
android:value="true" />
</activity>
App-Instanzen mit Drag-and-drop-Gesten verwalten
Im Mehrfenstermodus können Nutzer eine neue App-Instanz starten, indem sie ein Ansichtselement aus dem App-Fenster ziehen. Nutzer können auch Elemente zwischen Instanzen derselben App verschieben.
In Android 15 werden zwei Flags eingeführt, mit denen das Ziehverhalten angepasst werden kann:
DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG: Gibt an, dass ein nicht verarbeiteter Drag an das System delegiert werden soll, um gestartet zu werden, wenn kein sichtbares Fenster den Drop verarbeitet. Wenn dieses Flag verwendet wird, muss der AufruferClipDatamit einemClipData.Itembereitstellen, das eine unveränderlicheIntentSenderfür eine zu startende Aktivität enthält (sieheClipData.Item.Builder#setIntentSender()). Das System kann den Intent basierend auf Faktoren wie der aktuellen Bildschirmgröße oder dem Fenstermodus starten oder nicht. Wenn der Intent nicht vom System gestartet wird, wird er über den normalen Drag-Vorgang abgebrochen.DRAG_FLAG_GLOBAL_SAME_APPLICATION: Gibt an, dass ein Drag-Vorgang Fenstergrenzen überschreiten kann (für mehrere Instanzen derselben Anwendung).Wenn [
startDragAndDrop()][20] mit diesem Flag aufgerufen wird, können nur sichtbare Fenster derselben Anwendung am Drag-Vorgang teilnehmen und die gezogenen Inhalte empfangen.
Das folgende Beispiel zeigt, wie Sie diese Flags mit startDragAndDrop() verwenden:
// Assuming 'view' is the View that initiates the drag
view.setOnLongClickListener {
// Create an IntentSender for the activity you want to launch
val launchIntent = Intent(view.context, NewInstanceActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
view.context,
0,
launchIntent,
PendingIntent.FLAG_IMMUTABLE // Ensure the PendingIntent is immutable
)
// Build the ClipData.Item with the IntentSender
val item = ClipData.Item.Builder()
.setIntentSender(pendingIntent.intentSender)
.build()
// Create ClipData with a simple description and the item
val dragData = ClipData(
ClipDescription("New Instance Drag", arrayOf(ClipDescription.MIMETYPE_TEXT_PLAIN)),
item
)
// Combine the drag flags
val dragFlags = View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG or
View.DRAG_FLAG_GLOBAL_SAME_APPLICATION
// Start the drag operation
view.startDragAndDrop(
dragData, // The ClipData to drag
View.DragShadowBuilder(view), // A visual representation of the dragged item
null, // Local state object (not used here)
dragFlags // The drag flags
)
true // Indicate that the long click was consumed
}
Zusätzliche Optimierungen
Sie können das Starten von Apps anpassen und Apps vom Desktop-Freiform-Fenstermodus in den Vollbildmodus wechseln.
Standardgröße und ‑position festlegen
Nicht alle Apps, auch wenn sie in der Größe angepasst werden können, benötigen ein großes Fenster, um Nutzern einen Mehrwert zu bieten.
Mit der Methode ActivityOptions#setLaunchBounds() können Sie eine Standardgröße und ‑position für den Start einer Aktivität festlegen.
Hier ist ein Beispiel dafür, wie Sie Startgrenzen für eine Aktivität festlegen:
val options = ActivityOptions.makeBasic()
// Define the desired launch bounds (left, top, right, bottom in pixels)
val launchBounds = Rect(100, 100, 700, 600) // Example: 600x500 window at (100,100)
// Apply the launch bounds to the ActivityOptions
options.setLaunchBounds(launchBounds)
// Start the activity with the specified options
val intent = Intent(this, MyActivity::class.java)
startActivity(intent, options.toBundle())
Vollbildmodus über den Desktopbereich aktivieren
Apps können in den Vollbildmodus wechseln, indem sie Activity#requestFullScreenMode() aufrufen.
Mit dieser Methode wird die App direkt aus dem Desktop-Fenstersystem im Vollbildmodus angezeigt.
Verwenden Sie den folgenden Code, um den Vollbildmodus über eine Aktivität anzufordern:
// In an Activity
fun enterFullScreen() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // Android 15 (U)
requestFullScreenMode()
}
}