Android'de kenardan kenara (edge-to-edge) ve tahmini geri (predictive back): 2026'da artık zorunlu olan ve arayüzünüzü bozmadan nasıl uygulanır
Kenardan kenara artık API 35+ için zorunlu, tahmini geri ise varsayılan hareket oldu. Compose insets, WindowInsets ve PredictiveBackHandler için pratik bir rehber.
Bu döngüde iki Android arayüz değişikliği artık isteğe bağlı olmaktan çıktı. API 35+ hedefleyen uygulamalarda kenardan kenara (edge-to-edge) zorunlu hale geldi — artık sistemin sizin için opak çubuklar çizmesine izin verecek şekilde vazgeçemiyorsunuz. Ve tahmini geri — bir geri kaydırma hareketinin, siz tamamlamadan önce nereye gideceğinizi önizleyen versiyonu — artık deneysel bir bayrak değil, gesture-nav cihazlarda varsayılan etkileşim. İkisi de bir yeniden tasarım değil. İkisi de bunun için yapılmamış bir arayüzü gözle görülür şekilde bozacak ve başarısızlık modu ikisinde de aynı: test ettiğiniz emülatörde sorunsuz çalışır, çentikli veya üç tuşlu navigasyonu kapatılmış gerçek bir telefonda bozuk görünür.
İşte gerçekte ne değişti ve beş uygulama boyunca her iki durumda da ekranları doğru tutan Compose kodu.
Kenardan kenara artık bir tercih değil
API 35’ten önce enableEdgeToEdge(), belirli bir ekran için isteğe bağlı olarak açtığınız bir şeydi — yarı saydam bir durum çubuğu altında içeriğin akmasını isteyen uygulamalar için hoş bir ekstraydı. API 35’i hedeflemek bu tercihi kaldırıyor: Window.setDecorFitsSystemWindows(false) davranışı zorunlu kılınıyor, sistem çubukları saydam hale geliyor ve siz hiçbir şey çağırmasanız bile kök içeriğiniz onların arkasında çiziliyor.
Pratik etkisi şu: durum çubuğunun ve navigasyon çubuğunun kendi alanlarını ayırdığını varsayan her layout, artık içeriğin fiziksel piksel sıfırdan başladığını görüyor. Bir üst app bar’ın başlığı saatin altında oturuyor. Bir alt navigasyon çubuğunun ikonları gesture pilinin altında oturuyor. Bu bir görsel cila sorunu değil — gerçek bir cihazda kullanıcıların arayüzünüzün alt sırasına dokunamadığı anlamına geliyor.
Çözüm “her yere padding ekle” değil. WindowInsets’i doğru sınırda, bir kez uygulamak; böylece sistem çubukları tam olarak içeriğin ihtiyaç duyduğu yerde alan ayırır, başka hiçbir yerde değil.
setContent {
AppTheme {
Scaffold(
contentWindowInsets = WindowInsets.safeDrawing,
topBar = { TopAppBar(title = { Text("Stocky") }) },
) { padding ->
LazyColumn(contentPadding = padding) {
items(pantryItems) { PantryRow(it) }
}
}
}
}
Scaffold, kendisine verilen üst bar ve alt bar için zaten hesap yaptığından, çoğu ekranın tek bir parametreyi bağlamaktan başka bir şeye ihtiyacı yok. Tuzak, bunu iki kez yapmak: Scaffold, padding değerine safe-drawing insets uygular; bir alt bileşen de bunun üstüne .systemBarsPadding() çağırırsa, durum çubuğunun altında iki katı boşluk elde edersiniz — tasarımda bir hata gibi görünen ama aslında insets kodundaki bir hata olan boş bir şerit.
Insets’in elle ele alınması gereken yerler
Her ekran Scaffold üzerinden geçmiyor. Granyn, Stocky ve Mintly boyunca elle düzeltmek zorunda kaldığım üç nokta:
- Alt sayfalar (bottom sheet) ve diyaloglar. Bir
ModalBottomSheet, kendi yüzeyini üstScaffold’un padding’inin dışında çizer; bu yüzden içeriğinin en içteki sütununda kendi.navigationBarsPadding()’ine ihtiyacı vardır, aksi halde son satır gesture çubuğunun altında oturur. - Klavye.
WindowInsets.ime,navigationBars’tan ayrı bir inset’tir ve klavye açılıp kapandıkça animasyonla değişir. Bir ekranın altına sabitlenmiş bir metin alanının.navigationBarsPadding()’e değil.imePadding()’e ihtiyacı vardır — klavye kapalıyken ikisi çakışır, açıldığı anda birbirinden ayrılır. - Tam ekran görseller ya da başlıklar. İçeriğin durum çubuğunun altında bilinçli olarak çizilmesini istediğiniz durumlarda — bir ekran görüntüsü galerisi, bir hero görsel — üstüne yerleştirilmiş etkileşimli kontrollere (geri butonu, paylaş ikonu) tüm konteyneri padding’lemek yerine
.windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Top))uygulayın, yoksa istediğiniz efekti kaybedersiniz.
Bir kullanıcı bulmadan önce bunların çoğunu yakalayan tek alışkanlık: emülatörde gesture navigasyonu ve durum çubuğu için “Demo mode” özelleştirmesini açık tutmak, ve her ekranı çentik simülasyonu açıkken kontrol etmek. Üç tuşlu navigasyon ve düz bir durum çubuğu, göndereceğiniz insets hatalarının neredeyse hepsini gizler.
Tahmini geri: sert bir kesmeden bir önizlemeye
Diğer değişiklik davranışsal, layout’la ilgili değil. Tahmini geri, kullanıcı parmağını kaldırmadan önce sistemin bir geri hareketinin nereye varacağını göstermesine izin verir — altındaki ekranın küçülen bir önizlemesi — böylece kullanıcı hedefi görüp kaydırma sırasında vazgeçebilir. Buna dahil olmayan uygulamalar hâlâ düz, anlık bir ekran değişimi alır; hareket çalışır, ama cihazdaki tahmini geriye duyarlı her diğer uygulamanın yanında bir jump cut gibi görünür.
Buna dahil olmak bir manifest bayrağı artı bir Compose callback’i gerektirir:
<!-- AndroidManifest.xml -->
<application android:enableOnBackInvokedCallback="true">
PredictiveBackHandler(enabled = showDetail) { progress ->
try {
progress.collect { backEvent ->
// backEvent.progress: 0f (başlangıç) → 1f (tamamlandı)
scale = 1f - (backEvent.progress * 0.1f)
}
showDetail = false // hareket tamamlandı
} catch (e: CancellationException) {
scale = 1f // hareket iptal edildi — eski haline dön
}
}
PredictiveBackHandler (androidx.activity.compose’dan), BackHandler’dan gelen insanların takıldığı kısım olan tek bir callback yerine size bir ilerleme olayları Flow’u verir. Bunu hareket süresince toplarsınız, backEvent.progress’e göre bir animasyon çalıştırırsınız ve iptal edilen bir kaydırmadaki CancellationException bir hata değil, normal çıkış yoludur — sistemin size kullanıcının taahhüt etmeden önce bıraktığını söylediği yer burasıdır. Bunu tam olarak Mintly’nin oturum detay ekranında kullandım: zamanlayıcı görünümü artık geri kaydırdıkça hafifçe küçülüyor ve arkasındaki listeyi ortaya çıkarıyor, erken bırakırsanız akış sadece kaybolmak yerine temiz bir şekilde tam boyuta geri dönüyor.
Göndermeden önce gerçekten kontrol edilecekler
- Her ekran, gesture navigasyon açık ve üç tuşlu navigasyon kapalıyken doğru render ediliyor — çoğu yeni cihazın geldiği mod bu.
- Durum çubuğunun altında çift padding’lenmiş boşluk yok (yukarıdaki
Scaffold+ elle.systemBarsPadding()tuzağı). - Alt sayfalar ve snackbar’lar, donanım navigasyon tuşu olmayan bir cihazda gesture çubuğunu geçiyor.
- Bir ekranın altına yakın metin alanları
.imePadding()kullanıyor ve klavye açıldığında zıplamıyor. - En az bir gerçek navigasyona sahip ekranda (sadece ilk test ettiğiniz ekran değil) tahmini geri bağlanmış, böylece hareket ekranlar arasında tutarsız hissettirmiyor.
Bir kez karşılaştıktan sonra bunların hiçbiri zor değil. Sadece üç tuşlu navigasyonlu standart bir emülatörde görünmez — ki bu tam olarak çoğumuzun varsayılan olarak çalışır bıraktığı kurulum — ve tam olarak bu yüzden olması gerekenden daha sık bozuk gönderiliyor.
// İlgili okumalar
Günlükten dahası
Android In-App Review API: sıkıcı olmadan puan istemek
Google'ın In-App Review API'sine pratik bir rehber — gerçekte nasıl çalıştığı, ne zaman tetiklenmesi gerektiği ve alışılmış 'bizi puanlayın' popup'ının Play Store puanınızı sessizce nasıl zedelediği.
Android uygulama kısayolları ve Hızlı Ayarlar Karosu: uygulamayı açmadan su kaydetmek
Android'in dinamik ShortcutManager API'sine ve TileService'e pratik bir rehber — tek dokunuşlu bir eylemin uygulamayı tamamen atlamasını nasıl sağlarsınız, çoğu uygulamayı çuvallatan tuzaklarla birlikte.
Android'de 2026'da ön plan servis türleri: özelliğinize gerçekten uyanı seçmek
Android'in ön plan servis türü kısıtlamalarına pratik bir rehber — dataSync, mediaPlayback, specialUse, shortService — ve öldürülmeden ya da reddedilmeden doğru olanı nasıl seçeceğiniz.