Pencereli görüntüleme, kullanıcıların yeniden boyutlandırılabilir uygulama pencerelerinde aynı anda birden fazla uygulama çalıştırmasına olanak tanıyarak çok yönlü, masaüstüne benzer bir deneyim sunar.
Şekil 1'de, pencereli görüntüleme etkinleştirilmiş ekranın düzenini görebilirsiniz. Önemli noktalar:
- Kullanıcılar birden fazla uygulamayı aynı anda yan yana çalıştırabilir.
- Görev çubuğu, ekranın alt kısmında sabit bir konumda bulunur ve çalışan uygulamaları gösterir. Kullanıcılar, hızlı erişim için uygulamaları sabitleyebilir.
- Yeni özelleştirilebilir başlık çubuğu, her pencerenin üst kısmını simge durumuna küçültme ve ekranı kaplama gibi kontrollerle süsler.
Uygulamalar, Android tabletlerde varsayılan olarak tam ekran açılır. Bir uygulamayı pencereli görüntüleme modunda başlatmak için ekranın üst kısmındaki pencere tutma yerine basılı tutun ve tutma yerini kullanıcı arayüzünde sürükleyin (Şekil 2'de gösterildiği gibi).
Bir uygulama pencereli görüntüleme modunda açıldığında diğer uygulamalar da masaüstü pencerelerinde açılır.
Kullanıcılar, pencere tutma yerine dokunduklarında veya tıkladıklarında ya da Meta tuşu (Windows, Komut veya Arama) + Ctrl + Aşağı klavye kısayolunu kullandıklarında pencere tutma yerinin altında gösterilen menüden de pencereli görüntülemeyi etkinleştirebilir.
Kullanıcılar, tüm etkin pencereleri kapatarak veya masaüstü penceresinin üst kısmındaki pencere tutma yerini tutup uygulamayı ekranın üst kısmına sürükleyerek pencereli görüntülemeden çıkabilir. Meta + H klavye kısayolu da pencereli görüntülemeden çıkıp uygulamaları tekrar tam ekranda çalıştırır.
Masaüstü pencereli görüntüleme özelliğine dönmek için Son Kullanılanlar ekranında masaüstü alanı kartına dokunun veya kartı tıklayın.
Uygulama düzeninizi masaüstü benzeri bir ortam için optimize etme
Masaüstü deneyimi için tasarım yapmak, daha geniş ekran alanı, fare ve klavye girişinin hassasiyeti ve yüksek üretkenlik beklentisi nedeniyle mobil tasarımdan önemli ölçüde farklı olabilir.
Jetpack WindowManager, geliştiricilerin masaüstü kullanıcı arayüzünü ne zaman göstereceklerine karar vermelerine yardımcı olan, fikir sahibi bir API sağlar. Masaüstü kullanıcı arayüzü genellikle daha yüksek bilgi yoğunluğuna, farklı gezinme kalıplarına ve optimize edilmiş fare etkileşimlerine sahiptir.
lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { windowInfoTracker.windowEngagementInfo(this@DesktopWindowingActivity) .collect { windowEngagementInfo -> if(windowEngagementInfo.hasEngagementMode(WindowEngagementInfo.EngagementMode.PRECISE_POINTER)){ showDesktopOptimizedUI() }else { showTouchOptimizedUI() } } } }
Daha fazla bilgi edinmek için Masaüstü için tasarım başlıklı makaleyi inceleyin.
Yeniden boyutlandırılabilirlik ve uyumluluk modu
Pencereli görüntüleme modunda, yönü kilitli uygulamalar serbestçe yeniden boyutlandırılabilir. Bu, bir etkinlik dikey yöne kilitli olsa bile kullanıcıların uygulamayı yatay yönlü bir pencereye yeniden boyutlandırabileceği anlamına gelir.
Yeniden boyutlandırılamaz olarak tanımlanan uygulamaların (yani resizeableActivity = false) kullanıcı arayüzü, aynı en boy oranı korunarak ölçeklendirilir.
Yönü kilitleyen veya yeniden boyutlandırılamaz olarak tanımlanan kamera uygulamalarının kamera vizörleri için özel bir işlem uygulanır: Pencere tamamen yeniden boyutlandırılabilir ancak vizör aynı en-boy oranını korur. Uygulamaların her zaman dikey veya yatay modda çalıştığı varsayıldığında, uygulamalar önizlemenin veya çekilen görüntünün yönünün ya da en boy oranının yanlış hesaplanmasına yol açan varsayımlarda bulunur. Bu da görüntülerin gerilmesine, yan veya baş aşağı görünmesine neden olur.
Uygulamalar tamamen duyarlı kamera vizörleri uygulamaya hazır olana kadar özel işlem, yanlış varsayımların neden olabileceği etkileri azaltan daha temel bir kullanıcı deneyimi sunar.
Kamera uygulamaları için uyumluluk modu hakkında daha fazla bilgi edinmek isterseniz Cihaz uyumluluğu modu başlıklı makaleyi inceleyin.
Özelleştirilebilir başlık ekleri
Pencereli görüntüleme modunda çalışan tüm uygulamalarda, yoğun içerik modunda bile başlık çubuğu bulunur. Uygulamanızın içeriğinin gizlenmesini önlemek ve özel kullanıcı arayüzü öğelerini doğrudan başlık alanına çizmek için bu çubuğu özelleştirebilirsiniz.
Uygulama
Başlık çubuğuna özel içerik çizmek için ilk adım, başlık çubuğu arka planını şeffaf hale getirmektir. Bunu yapmak için WindowInsetsController ile APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND işaretini kullanabilirsiniz.
window.insetsController?.setSystemBarsAppearance( WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND, WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND )
Üstbilgi çubuğu şeffaf hale geldikten sonra üstbilgi alanını uygulamanızın tasarımına uyacak şekilde şekillendirebilirsiniz. Çubuğun mevcut olup olmadığını tespit etmek ve düzeninize uygun yüksekliği veya dolguyu uygulamak için WindowInsets.isCaptionBarVisible kullanın.
@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): Sistem çubuklarının görsel stilini yapılandırır. İlk parametre, hedef görünüm işaretlerini tanımlarken ikinci parametre, hangi işaretlerin değiştirileceğini kontrol eden bir maske görevi görür.windowInsetsTopHeight(): Composable'ınızın yüksekliğini sistemin başlık çubuğuyla eşleşecek şekilde otomatik olarak ayarlar. Böylece özel arka planınız, piksel değerlerini sabit kodlamadan altyazı alanını doldurur.WindowInsets.captionBar: Masaüstü pencereli görüntüleme kontrollerinin (Kapat, Ekranı kapla vb.) boyutlarını sağlar. Böylece kullanıcı arayüzünüz, masaüstü pencereli görüntüleme moduna girerken veya bu moddan çıkarken otomatik olarak ölçeklendirilir ya da gizlenir.
Daha fazla bilgi için Pencere iç metinleri hakkında bölümüne bakın. Başlık çubuğunda başlığın yanı sıra Google Chrome'daki gibi sekmeler, arama çubukları veya profil avatarları gibi diğer kullanıcı arayüzü öğelerini de gösterebilirsiniz.
Kullanıcı arayüzü
Android 15, kullanıcı arayüzünüzün sistem düğmeleriyle çakışmasını önlemek için WindowInsets#getBoundingRects() yöntemini sunar. Yöntem, sistem öğelerinin kapladığı alanları temsil eden Rect nesnelerinin listesini döndürür. Başlık çubuğunda kalan alan, özel içerikleri güvenle yerleştirebileceğiniz güvenli bölgedir.
APPEARANCE_LIGHT_CAPTION_BARS kısayolunu kullanarak açık ve koyu temalar için sistem altyazısı öğelerinin görünümünü değiştirin. İç kısımlara erişmek için Compose'da WindowInsets.Companion.captionBar(), Görünümler'de ise WindowInsets.Type.captionBar() kullanın.
Daha fazla bilgi için Pencere iç metinleri hakkında bölümüne bakın.
Çoklu görev ve aynı anda çalışan birden çok kopya desteği
Çoklu görev, pencereli görüntülemenin temelini oluşturur ve uygulamanızın birden fazla örneğine izin vermek, kullanıcıların üretkenliğini büyük ölçüde artırabilir.
Android 15'ten itibaren PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI kullanabilirsiniz. AndroidManifest.xml uygulamanızda bu özelliği ayarlayarak sistem kullanıcı arayüzünün, uygulamanın birden fazla örnekte başlatılması için seçenekler ("Yeni Pencere" düğmesi gibi) sunması gerektiğini belirtirsiniz.
<application>
<property
android:name="android.window.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI"
android:value="true" />
</application>
Not: Masaüstü pencereli görüntüleme ve diğer çok pencereli ortamlarda yeni görevler yeni bir pencerede açılır. Bu nedenle, uygulamanız birden fazla görev başlattığında kullanıcı yolculuğunu tekrar kontrol edin.
Uygulama örneklerini sürükleme hareketleriyle yönetme
Çoklu pencere modunda kullanıcılar, bir kullanıcı arayüzü öğesini (ör. sekme veya doküman) uygulama penceresinin dışına sürükleyerek yeni bir uygulama örneği başlatabilir. Kullanıcılar, aynı uygulamanın farklı örnekleri arasında da öğe taşıyabilir.
Sürükle ve bırak yöntemiyle veri aktarma
Kullanıcıların içeriği uygulamanızın başka bir örneğine sürüklemesine veya içeriği ekranın boş bir alanına bırakarak yeni bir örnek oluşturmasına olanak tanıyan aynı anda çalışan birden çok kopya sürükle ve bırak işlemi için bir composable'ı sürükleme kaynağı olarak yapılandırmak üzere dragAndDropSource değiştiricisini kullanın. Lambda'sında, aktarılacak verileri içeren ClipData ve aynı anda çalışan birden çok kopya davranışını yapılandırmak için işaretleri ileterek DragAndDropTransferData değerini döndürün.
Android 15, masaüstü tarzı pencereleme ve aynı anda çalışan birden çok kopya etkileşimleri için iki önemli işaret sunar:
DRAG_FLAG_GLOBAL_SAME_APPLICATION: Sürükleme işleminin pencere sınırlarını aşabileceğini gösterir (aynı uygulamanın birden fazla örneği için).startDragAndDrop()bu işaret ayarlanmış olarak çağrıldığında yalnızca aynı uygulamaya ait görünür pencereler sürükleme işlemine katılabilir ve sürüklenen içeriği alabilir.
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( clipData = ClipData.newPlainText("label", "Your data"), flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION ) }
DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG: Sürüklenen içeriği ekranın boş bir alanına bırakarak uygulamanızın yeni bir örneğini başlatmalarına olanak tanır (bırakma işlemini başka bir pencere işlemiyorsa).- Bu işareti kullanırken
ClipData.Item.Builder#setIntentSender()kullanarak birIntentSendersağlamanız gerekir. Sistem, işlenmeyen bir bırakma işlemi gerçekleşirse yeni etkinliği başlatmak için bunu kullanır.
- Bu işareti kullanırken
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, ) }
Aktarılan verileri alma
Başka bir örnekten veri kabul etmek için dragAndDropTarget değiştiricisini kullanın.
Veriler farklı bir örnekten veya uygulamadan geliyorsa izinleri açıkça istemeniz gerekir.
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 } } )
Temel adımlar:
- Filtre: Gelen verilerin (MIME türü) desteklenip desteklenmediğini kontrol etmek için
shouldStartDragAndDropkullanın. - İzinler: Verilere erişmek için
requestDragAndDropPermissions(event)yöntemini çağırın. - İşleme:
onDropgeri çağırmasındaki verileri ayıklayın.
Ek optimizasyonlar
Uygulama başlatma işlemlerini özelleştirme ve uygulamaları pencereli görüntülemeden tam ekrana geçirme
Varsayılan boyutu ve konumu belirtme
Yeniden boyutlandırılabilir olsa bile tüm uygulamaların kullanıcıya değer sunmak için büyük bir pencereye ihtiyacı yoktur. Bir etkinlik başlatıldığında varsayılan boyut ve konum belirtmek için ActivityOptions#setLaunchBounds() yöntemini kullanabilirsiniz.
Masaüstü alanından tam ekrana geçme
Uygulamalar, Activity#requestFullScreenMode() yöntemini çağırarak tam ekrana geçebilir. Bu yöntem, uygulamayı doğrudan pencereli görüntüleme modundan tam ekran olarak gösterir.