Mode jendela desktop memungkinkan pengguna menjalankan beberapa aplikasi secara bersamaan di jendela aplikasi yang dapat diubah ukurannya untuk pengalaman serbaguna seperti desktop.
Pada gambar 1, Anda dapat melihat organisasi layar dengan pengaktifan mode jendela desktop. Hal-hal yang perlu diperhatikan:
- Pengguna dapat menjalankan beberapa aplikasi secara berdampingan secara bersamaan.
- Taskbar berada di posisi tetap di bagian bawah layar yang menampilkan aplikasi yang sedang berjalan. Pengguna dapat menyematkan aplikasi untuk akses cepat.
- Panel header baru yang dapat disesuaikan menghiasi bagian atas setiap jendela dengan kontrol seperti minimalkan dan maksimalkan.
Secara default, aplikasi dibuka dalam layar penuh di tablet Android. Untuk meluncurkan aplikasi di mode jendela desktop, tekan lama tuas jendela di bagian atas layar dan tarik tuas di dalam UI, seperti yang terlihat pada gambar 2.
Saat aplikasi terbuka di jendela desktop, aplikasi lain juga akan terbuka di jendela desktop.
Pengguna juga dapat memanggil penataan jendela desktop dari menu yang muncul di bawah tuas jendela saat Anda mengetuk atau mengklik tuas atau menggunakan pintasan keyboard Tombol Meta (Windows, Command, atau Penelusuran) + Ctrl + Bawah.
Pengguna keluar dari penataan jendela desktop dengan menutup semua jendela aktif atau dengan menarik tuas jendela di bagian atas jendela desktop dan menarik aplikasi ke bagian atas layar. Pintasan keyboard Meta + H juga akan keluar dari tampilan jendela desktop dan menjalankan aplikasi dalam layar penuh lagi.
Untuk kembali ke penataan jendela desktop, ketuk atau klik kartu ruang desktop di layar Terbaru.
Mode pengubahan ukuran dan kompatibilitas
Dalam mode jendela desktop, aplikasi dengan orientasi terkunci dapat diubah ukurannya secara bebas. Artinya, meskipun aktivitas dikunci ke orientasi potret, pengguna tetap dapat mengubah ukuran aplikasi ke jendela orientasi lanskap.
Aplikasi yang dinyatakan tidak dapat diubah ukurannya (yaitu, resizeableActivity = false) memiliki
UI yang diskalakan dengan tetap mempertahankan rasio aspek yang sama.
Aplikasi kamera yang mengunci orientasi atau dinyatakan tidak dapat diubah ukurannya memiliki perlakuan khusus untuk jendela bidik kameranya: jendela dapat diubah ukurannya sepenuhnya, tetapi jendela bidik mempertahankan rasio aspek yang sama. Dengan mengasumsikan aplikasi selalu berjalan dalam potret atau lanskap, aplikasi akan meng-hardcode atau membuat asumsi yang menyebabkan salah perhitungan orientasi atau rasio aspek pratinjau atau gambar yang diambil sehingga menghasilkan gambar yang terentang, miring, atau terbalik.
Hingga aplikasi siap menerapkan jendela bidik kamera yang sepenuhnya responsif, perlakuan khusus memberikan pengalaman pengguna yang lebih mendasar yang memitigasi efek yang mungkin disebabkan oleh asumsi yang salah.
Untuk mempelajari lebih lanjut mode kompatibilitas untuk aplikasi kamera, lihat Mode kompatibilitas perangkat.
Inset header yang dapat disesuaikan
Semua aplikasi yang berjalan dalam jendela desktop memiliki panel header, bahkan dalam mode imersi. Anda dapat menyesuaikan kolom ini untuk mencegah konten aplikasi Anda tertutup dan menggambar elemen UI kustom langsung ke ruang header.
Implementasi
Untuk menggambar konten kustom di panel header, langkah pertama adalah membuat latar belakang panel header menjadi transparan. Anda dapat melakukannya dengan menggunakan
flag APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND dengan
WindowInsetsController.
window.insetsController?.setSystemBarsAppearance( WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND, WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND )
Setelah kolom header transparan, Anda dapat menata area header agar sesuai dengan desain aplikasi Anda. Gunakan WindowInsets.isCaptionBarVisible untuk mendeteksi apakah panel hadir dan menerapkan tinggi atau padding yang sesuai ke tata letak Anda.
@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): Mengonfigurasi gaya visual pada kolom sistem. Parameter pertama menentukan flag tampilan target, sedangkan parameter kedua berfungsi sebagai mask untuk mengontrol flag spesifik mana yang diubah.windowInsetsTopHeight(): Otomatis menyetel tinggi Composable agar sesuai dengan kolom header sistem, sehingga membantu latar belakang kustom Anda mengisi area teks tanpa meng-hardcode nilai piksel.WindowInsets.captionBar: Menyediakan dimensi untuk kontrol jendela desktop (Tutup, Maksimalkan, dll.), sehingga UI Anda dapat diskalakan atau disembunyikan secara otomatis saat memasuki atau keluar dari jendela desktop.
Untuk mengetahui informasi selengkapnya, lihat Tentang inset jendela. Selain judul, Anda dapat menampilkan elemen UI lain di kolom teks, seperti tab—seperti di Google Chrome—kolom penelusuran, atau avatar profil.
Antarmuka pengguna
Untuk menghindari tumpang-tindih UI dengan tombol sistem, Android 15 menyediakan metode
WindowInsets#getBoundingRects(). Metode ini menampilkan daftar objek
Rect yang merepresentasikan area yang ditempati oleh elemen sistem. Ruang yang tersisa di kolom teks adalah area aman tempat Anda dapat menempatkan konten kustom dengan aman.
Alihkan tampilan elemen teks sistem untuk tema terang dan gelap menggunakan
APPEARANCE_LIGHT_CAPTION_BARS. Akses inset menggunakan
WindowInsets.Companion.captionBar() di Compose, atau
WindowInsets.Type.captionBar() di View.
Untuk mengetahui informasi selengkapnya, lihat Tentang inset jendela.
Dukungan multitasking dan multi-instance
Multitasking adalah inti dari mode jendela desktop, dan mengizinkan beberapa instance aplikasi Anda dapat sangat meningkatkan produktivitas pengguna.
Mulai dari Android 15, Anda dapat menggunakan
PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI. Dengan menyetel properti ini di
AndroidManifest.xml, Anda menentukan bahwa UI sistem harus menyediakan opsi
(seperti tombol "Jendela Baru") agar aplikasi diluncurkan dalam beberapa instance.
<application>
<property
android:name="android.window.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI"
android:value="true" />
</application>
Catatan: Dalam penyesuaian jendela desktop dan lingkungan multi-aplikasi lainnya, tugas baru dibuka di jendela baru, jadi periksa kembali perjalanan pengguna setiap kali aplikasi Anda memulai beberapa tugas.
Mengelola instance aplikasi dengan gestur menarik
Dalam mode multi-aplikasi, pengguna dapat memulai instance aplikasi baru dengan menarik elemen UI (seperti tab atau dokumen) keluar dari jendela aplikasi. Pengguna juga dapat memindahkan elemen di antara berbagai instance aplikasi yang sama.
Mentransfer data dengan menarik lalu melepas
Untuk mengonfigurasi composable sebagai sumber penarikan untuk tarik lalu lepas multi-instance
yang memungkinkan pengguna menarik konten ke instance lain aplikasi Anda, atau membuat instance
baru dengan melepaskan konten ke area kosong di layar—gunakan pengubah
dragAndDropSource. Di lambda-nya, kembalikan
DragAndDropTransferData, dengan meneruskan ClipData yang berisi data yang akan
ditransfer, dan flag untuk mengonfigurasi perilaku multi-instance.
Android 15 memperkenalkan dua tanda utama untuk mode jendela gaya desktop dan interaksi multi-instance:
DRAG_FLAG_GLOBAL_SAME_APPLICATION: Menunjukkan bahwa operasi penarikan dapat melintasi batas jendela (untuk beberapa instance dari aplikasi yang sama). JikastartDragAndDrop()dipanggil dengan setelan tanda ini, hanya jendela yang terlihat milik aplikasi yang sama yang dapat berpartisipasi dalam operasi penarikan dan menerima konten yang ditarik.
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( clipData = ClipData.newPlainText("label", "Your data"), flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION ) }
DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG: Memungkinkan pengguna memulai instance baru aplikasi Anda dengan melepaskan konten yang ditarik ke area kosong di layar, jika tidak ada jendela lain yang menangani pelepasan.- Saat menggunakan tanda ini, Anda harus memberikan
IntentSendermenggunakanClipData.Item.Builder#setIntentSender(), yang digunakan sistem untuk meluncurkan aktivitas baru jika terjadi pelepasan yang tidak tertangani.
- Saat menggunakan tanda ini, Anda harus memberikan
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, ) }
Menerima data yang ditransfer
Untuk menerima data dari instance lain, gunakan pengubah dragAndDropTarget.
Anda harus meminta izin secara eksplisit jika data berasal dari instance atau aplikasi yang berbeda.
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 } } )
Langkah-langkah utama:
- Filter: Gunakan
shouldStartDragAndDropuntuk memeriksa apakah data yang masuk (jenis MIME) didukung. - Izin: Panggil
requestDragAndDropPermissions(event)untuk mengakses data. - Tangani: Ekstrak data dalam callback
onDrop.
Pengoptimalan tambahan
Menyesuaikan peluncuran aplikasi dan mentransisikan aplikasi dari jendela desktop ke layar penuh.
Menentukan ukuran dan posisi default
Tidak semua aplikasi, meskipun dapat diubah ukurannya, memerlukan jendela besar untuk menawarkan nilai pengguna. Anda
dapat menggunakan metode ActivityOptions#setLaunchBounds() untuk menentukan ukuran
dan posisi default saat aktivitas diluncurkan.
Masuk ke layar penuh dari ruang desktop
Aplikasi dapat ditampilkan dalam layar penuh dengan memanggil Activity#requestFullScreenMode(). Metode
menampilkan aplikasi layar penuh langsung dari jendela desktop.