Android platformu, durum çubuğu ve gezinme çubuğu gibi sistem kullanıcı arayüzünü çizmekten sorumludur. Bu sistem kullanıcı arayüzü, kullanıcının kullandığı uygulamadan bağımsız olarak görüntülenir. WindowInsets
, uygulamanızın doğru alanda çizildiğinden ve kullanıcı arayüzünüzün sistem kullanıcı arayüzü tarafından gizlenmediğinden emin olmak için sistem kullanıcı arayüzü hakkında bilgiler sağlar.
Varsayılan olarak uygulamanızın kullanıcı arayüzü, durum çubuğu ve gezinme çubuğu gibi sistem kullanıcı arayüzü içinde yer alacak şekilde sınırlandırılmıştır. Bu, uygulamanızın içeriğinin sistem kullanıcı arayüzü öğeleri tarafından gizlenmemesini sağlar.
Ancak uygulamaların, sistem kullanıcı arayüzünün de gösterildiği bu alanlarda gösterilmesini etkinleştirmelerini öneririz. Bu, daha sorunsuz bir kullanıcı deneyimiyle sonuçlanır ve uygulamanızın, mevcut pencere alanından en iyi şekilde yararlanmasını sağlar. Bu ayrıca, özellikle yazılım klavyesini gösterirken ve gizlerken uygulamaların sistem kullanıcı arayüzüyle birlikte hareket etmesine olanak tanır.
Bu bölgelerde görüntülemeyi etkinleştirmek ve sistem kullanıcı arayüzünün arkasında içerik görüntülemek, uçtan uca geçiş olarak adlandırılır. Bu sayfada farklı ek öğe türlerini, uçtan uca geçişe nasıl dahil olacağınızı, kullanıcı arayüzünüze animasyon eklemek ve uygulamanızın bazı bölümlerinin anlaşılmasını önlemek için ekteki API'ları nasıl kullanacağınızı öğreneceksiniz.
Inset temel bilgileri
Uçtan uca uygulamalarda, önemli içeriklerin ve etkileşimlerin sistem kullanıcı arayüzü tarafından engellenmediğinden emin olmanız gerekir. Örneğin, gezinme çubuğunun arkasına bir düğme yerleştirilirse kullanıcı bu düğmeyi tıklayamayabilir.
Sistem kullanıcı arayüzünün boyutu ve yerleştirildiği yerle ilgili bilgiler, insets aracılığıyla belirtilir.
Sistem kullanıcı arayüzünün her bir bölümünde, boyutunu ve yerleştirildiği yeri açıklayan bir tür veri bulunur. Örneğin, durum çubuğu öğeleri durum çubuğunun boyutunu ve konumunu, gezinme çubuğu öğeleri ise gezinme çubuğunun boyutunu ve konumunu sağlar. Her bir ek türü, dört piksel boyutundan oluşur: üst, sol, sağ ve alt. Bu boyutlar, sistem kullanıcı arayüzünün, uygulama penceresinin karşılık gelen kenarlarından ne kadar uzandığını belirtir. Dolayısıyla, bu tür bir sistem kullanıcı arayüzüyle çakışmayı önlemek için uygulama kullanıcı arayüzünün bu miktara eklenmesi gerekir.
Aşağıdaki yerleşik Android ek türlerini WindowInsets
üzerinden kullanabilirsiniz:
Durum çubuklarını açıklayan ekler. Bunlar, bildirim simgelerini ve diğer göstergeleri içeren en üstteki sistem kullanıcı arayüzü çubuklarıdır. |
|
Görünür oldukları durumlar için durum çubuğu ekleri. Durum çubukları şu anda gizliyse (kapsamlı tam ekran moduna geçilmesi nedeniyle) ana durum çubuğunun alt öğeleri boş olur, ancak bu öğeler boş olmaz. |
|
Gezinme çubuklarını açıklayan ekler. Bunlar, cihazın sol, sağ veya alt tarafında bulunan ve görev çubuğunu veya gezinme simgelerini açıklayan sistem kullanıcı arayüzü çubuklarıdır. Bu ayarlar, kullanıcının tercih ettiği gezinme yöntemine ve görev çubuğuyla etkileşimde bulunma tercihine bağlı olarak çalışma zamanında değişebilir. |
|
Görünür oldukları durumlar için gezinme çubuğu iç öğeleri. Gezinme çubukları şu anda gizliyse (kapsamlı tam ekran moduna geçilmesi nedeniyle) ana gezinme çubuğunun öğeleri boş olur, ancak bu öğeler boş olmaz. |
|
Serbest biçimli bir pencerede (ör. üst başlık çubuğu) sistem kullanıcı arayüzü pencere süslemesini açıklayan ek. |
|
Altyazı çubuğu, görünür oldukları zamana göre ayarlanır. Altyazı çubukları şu anda gizliyse ana altyazı çubuğu öğeleri boş olur, ancak bu öğeler boş olmaz. |
|
Durum çubukları, gezinme çubukları ve altyazı çubuğunu içeren sistem çubuğu eklerinin birleşimi. |
|
Görünür oldukları zamanları belirlemek için sistem çubuğu ekleri. Sistem çubukları şu anda gizliyse (kapsamlı tam ekran moduna geçilmesi nedeniyle) ana sistem çubuğu iç öğeleri boş olur, ancak bu öğeler boş olmaz. |
|
Yazılım klavyesinin kapladığı alan miktarını açıklayan ek bilgiler. |
|
Mevcut klavye animasyonundan önce yazılım klavyesinin kapladığı alan miktarını açıklayan ek veriler. |
|
Mevcut klavye animasyonundan sonra yazılım klavyesinin kaplayacağı alan miktarını açıklayan ek veriler. |
|
Gezinme kullanıcı arayüzü hakkında daha ayrıntılı bilgileri açıklayan ve "dokunmaların" uygulama tarafından değil, sistem tarafından işleneceği alan miktarını belirten bir ek türü. Hareketle gezinme özelliğine sahip şeffaf gezinme çubukları için bazı uygulama öğelerine sistem gezinme kullanıcı arayüzü üzerinden dokunulabilir. |
|
Dokunulabilir öğe, görünür oldukları zamana ayarlanır. Dokunulabilir öğeler şu anda gizliyse (kapsamlı tam ekran moduna geçilmesi nedeniyle) dokunulabilir ana öğe kümeleri boş olur, ancak bu öğeler boş olmaz. |
|
Sistemin gezinme hareketlerini keseceği eklerin miktarını temsil eden ekler. Uygulamalar, bu hareketlerin sınırlı bir kısmının nasıl kullanılacağını |
|
Her zaman sistem tarafından işlenecek olan ve |
|
Ekran kesimiyle (çentik veya küçük iğne deliği) çakışmaması için gereken aralık miktarını temsil eden ekler. |
|
Şelale ekranının eğri alanlarını temsil eden ekler. Şelale ekranının kenarlarında, cihazın kenarlarında kaymaya başladığı kavisli alanlar vardır. |
Bu türler, içeriğin gizlenmemesini sağlayan üç "güvenli" iç küme türüyle özetlenir:
Bu "güvenli" ek türleri, temel platform eklerine bağlı olarak içeriği farklı şekillerde korur:
- Herhangi bir sistem kullanıcı arayüzünün altına çizilmemesi gereken içeriği korumak için
WindowInsets.safeDrawing
kullanın. Eklerin en yaygın kullanımı, sistem kullanıcı arayüzü tarafından gizlenen (kısmen veya tamamen) içeriğin çizilmesini önlemek içindir. - İçerikleri hareketlerle korumak için
WindowInsets.safeGestures
özelliğini kullanın. Bu, sistem hareketlerinin uygulama hareketleriyle (alt sayfalar, bantlar veya oyunlardaki hareketler gibi) çakışmasını önler. - İçeriğin görsel örtüşmemesi ve hareket çakışması olmaması için
WindowInsets.safeContent
'iWindowInsets.safeDrawing
veWindowInsets.safeGestures
kombinasyonu olarak kullanın.
Insets kurulumu
Uygulamanızın, içeriği nerede çekeceği konusunda tam kontrol sahibi olmak için bu kurulum adımlarını izleyin. Bu adımlar olmadan, uygulamanız sistem kullanıcı arayüzünün arkasına siyah veya düz renkler çizebilir ya da yazılım klavyesi ile eşzamanlı şekilde animasyon uygulamayabilir.
Activity.onCreate
içindenenableEdgeToEdge()
numaralı telefonu arayın. Bu çağrı, uygulamanızın sistem kullanıcı arayüzünün arkasında görüntülenmesini ister. Böylece uygulamanız, kullanıcı arayüzünü ayarlamak için bu eklerin nasıl kullanılacağını kontrol eder.Etkinliğinizin
AndroidManifest.xml
girişindeandroid:windowSoftInputMode="adjustResize"
değerini ayarlayın. Bu ayar, uygulamanızın yazılım IME'sinin boyutunu ek olarak almasına olanak tanır. Bu özelliği, IME göründüğünde ve uygulamanızda kaybolurken içeriği uygun şekilde yerleştirmek ve yerleştirmek için kullanabilirsiniz.<!-- in your AndroidManifest.xml file: --> <activity android:name=".ui.MainActivity" android:label="@string/app_name" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.MyApplication" android:exported="true">
API oluşturma
Tüm ek öğelerin işlenmesini Etkinliğiniz kontrol ettiğinde, içeriğin gizlenmediğinden ve etkileşimde bulunulabilir öğelerin sistem kullanıcı arayüzüyle çakışmadığından emin olmak için Compose API'lerini kullanabilirsiniz. Bu API'ler ayrıca uygulamanızın düzenini içerideki değişikliklerle senkronize eder.
Örneğin, tüm uygulamanızın içeriğine ek öğeler uygulamanın en temel yöntemi budur:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Box(Modifier.safeDrawingPadding()) { // the rest of the app } } }
Bu snippet, safeDrawing
pencere eklerini, uygulamanın tüm içeriğinin etrafına dolgu olarak uygular. Böylece etkileşimde bulunulabilir öğelerin sistem kullanıcı arayüzüyle çakışmaması sağlanmış olsa da hiçbir uygulama, uçtan uca bir etki yaratmak için sistem kullanıcı arayüzünün arkasına çizim yapmaz. Pencerenin tamamından en iyi şekilde yararlanmak için, eklerin uygulanacağı yerleri ekran ve bileşen bazında hassas olarak ayarlamanız gerekir.
Bu ek türlerinin tamamı, API 21'e geri taşınan IME animasyonlarıyla otomatik olarak canlandırılır. Ayrıca, bu iç öğeleri kullanan tüm düzenleriniz, içe aktarılan değerler değiştikçe otomatik olarak canlandırılır.
Composable düzenlerinizi ayarlamak için bu iç küme türlerini kullanmanın iki temel yolu vardır: dolgu değiştiricileri ve ek boyut değiştiricileri.
Dolgu değiştiriciler
Modifier.windowInsetsPadding(windowInsets: WindowInsets)
, belirtilen pencere eklerini dolgu olarak uygular ve Modifier.padding
tarafından yapılan gibi davranır.
Örneğin, Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
, güvenli çizim eklerini 4 kenarın hepsine dolgu olarak uygular.
En yaygın inset türleri için birkaç yerleşik yardımcı program yöntemi de vardır.
Modifier.safeDrawingPadding()
, Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
ile eşdeğer olan bu yöntemlerden biridir. Diğer küme türleri için de
benzer değiştiriciler vardır.
Ek boyut değiştiriciler
Aşağıdaki değiştiriciler, bileşenin boyutunu eklerin boyutuna ayarlayarak bir miktar pencere içi öğe uygular:
windowInsets başlangıç tarafını genişlik olarak uygular (ör. |
|
windowInsets öğesinin son tarafını genişlik olarak uygular (ör. |
|
Yükseklik olarak windowInsets öğesinin üst tarafını ( |
|
|
Yükseklik olarak windowInsets alt tarafını ( |
Bu değiştiriciler, özellikle iç kısımda yer kaplayan bir Spacer
boyutunu boyutlandırmak için yararlıdır:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Veri tüketimi
İçe yerleştirilmiş dolgu değiştiriciler (windowInsetsPadding
ve safeDrawingPadding
gibi yardımcılar), içe aktarılanların dolgu olarak uygulanan bölümünü otomatik olarak tüketir. Kompozisyon ağacında daha derine inerken iç içe yerleştirilmiş iç dolgu değiştiricileri ve iç küme boyut değiştiricileri, iç içe yerleştirilmiş dolgu değiştiricilerin bir kısmının zaten dış içe dolgu değiştiricileri tarafından kullanıldığını bilir ve çok fazla boşluk oluşmasına yol açacak şekilde eklerin aynı kısmını birden fazla kez kullanmaktan kaçınır.
Ek öğeler tüketilmişse ek boyut değiştiricileri, aynı veri parçasını birden fazla kez kullanmaktan da kaçınır. Ancak doğrudan boyutlarını değiştirdikleri için ekleri kendileri tüketmezler.
Bunun sonucunda, iç içe yerleştirme dolgu değiştiricileri her composable'a uygulanan dolgu miktarını otomatik olarak değiştirir.
Önceki LazyColumn
örneğine bakıldığında, LazyColumn
, imePadding
değiştiricisi tarafından yeniden boyutlandırılmaktadır. LazyColumn
içindeki son öğe, sistem çubuklarının alt kısmının yüksekliğine eşit olacak şekilde boyutlandırılır:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
IME kapatıldığında, IME'nin yüksekliği olmadığından imePadding()
değiştiricisi dolgu uygulamaz. imePadding()
değiştiricisi dolgu uygulamadığından hiçbir iç içe geçilmez ve Spacer
öğesinin yüksekliği, sistem çubuklarının alt tarafının boyutu olur.
IME açıldığında, IME içinde gösterilen öğeler IME'nin boyutuyla eşleşecek şekilde canlandırılır ve imePadding()
değiştiricisi, IME açılırken LazyColumn
boyutunu yeniden boyutlandırmak için alt dolgu uygulamaya başlar. imePadding()
değiştiricisi alt dolgu uygulamaya başladıkça bu miktarda iç dolgu da kullanmaya başlar. Bu nedenle, imePadding()
değiştiricisi tarafından zaten sistem çubukları için uygulanan boşlukların bir parçası olarak Spacer
yüksekliği azalmaya başlar. imePadding()
değiştiricisi, sistem çubuklarından daha büyük bir alt dolgu miktarı uyguladığında Spacer
yüksekliği sıfır olur.
IME kapatıldığında, değişiklikler tersten gerçekleşir: imePadding()
, sistem çubuklarının alt tarafından daha az uygulandığında Spacer
sıfır yüksekliğinden genişlemeye başlar, son olarak da IME tamamen canlandırıldıktan sonra Spacer
, sistem çubuklarının alt tarafının yüksekliğiyle eşleşir.
Bu davranış, tüm windowInsetsPadding
değiştiricileri arasındaki iletişimle gerçekleştirilir ve başka birkaç şekilde etkilenebilir.
Modifier.consumeWindowInsets(insets: WindowInsets)
, iç öğeleri de Modifier.windowInsetsPadding
ile aynı şekilde tüketir ancak tüketilen iç öğeleri dolgu olarak uygulamaz. Bu, ek boyut değiştiricileriyle birlikte, kardeşlere belirli miktarda ekin zaten tüketildiğini belirtmek için yararlıdır:
Column(Modifier.verticalScroll(rememberScrollState())) { Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars)) Column( Modifier.consumeWindowInsets( WindowInsets.systemBars.only(WindowInsetsSides.Vertical) ) ) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) } Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) }
Modifier.consumeWindowInsets(paddingValues: PaddingValues)
, WindowInsets
bağımsız değişkenine sahip sürüme çok benzer şekilde davranır ancak kullanımı rastgele bir PaddingValues
alır. Bu, sıradan bir Modifier.padding
veya sabit yükseklikte yer tutucular gibi, içe yerleştirilmiş dolgu değiştiriciler dışındaki bir mekanizma tarafından dolgu veya boşluk sağlandığında onları bilgilendirmek açısından kullanışlıdır:
@OptIn(ExperimentalLayoutApi::class) Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
Tüketim olmadan ham pencere eklerinin gerektiği durumlarda doğrudan WindowInsets
değerlerini kullanın veya tüketimden etkilenmeyen eklerin PaddingValues
kadarını döndürmek için WindowInsets.asPaddingValues()
değerini kullanın.
Bununla birlikte, aşağıdaki uyarılar nedeniyle mümkün olduğunda pencere iç öğeleri dolgu değiştiricileri ve pencere boyutu değiştiricileri kullanmayı tercih edin.
Insets ve Jetpack Compose aşamaları
Compose, alt öğeleri güncellemek ve canlandırmak için temel AndroidX temel API'lerini kullanır. Bu API'ler, iç öğeleri yöneten temel platform API'lerini kullanır. Bu platform davranışı nedeniyle, eklerin Jetpack Composer aşamalarıyla özel bir ilişkisi vardır.
Eklerin değeri, bileşim aşamasından sonra ancak düzen aşamasından önce güncellenir. Bu, bileşimdeki eklerin değerinin okunurken genellikle bir kare geciken ek değeri kullanıldığı anlamına gelir. Bu sayfada açıklanan yerleşik değiştiriciler, eklerin değerlerini düzen aşamasına kadar kullanarak gecikme yaşanacak şekilde oluşturulmuştur. Bu, içe eklenen değerlerin güncellendikçe aynı çerçevede kullanılmasını sağlar.
WindowInsets
ile klavye IME animasyonları
Kapsayıcının en altına doğru kaydırılırken IME'yi otomatik olarak açıp kapatmak için bir kaydırma kapsayıcıya Modifier.imeNestedScroll()
uygulayabilirsiniz.
class WindowInsetsExampleActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, false) setContent { MaterialTheme { MyScreen() } } } } @OptIn(ExperimentalLayoutApi::class) @Composable fun MyScreen() { Box { LazyColumn( modifier = Modifier .fillMaxSize() // fill the entire window .imePadding() // padding for the bottom for the IME .imeNestedScroll(), // scroll IME at the bottom content = { } ) FloatingActionButton( modifier = Modifier .align(Alignment.BottomEnd) .padding(16.dp) // normal 16dp of padding for FABs .navigationBarsPadding() // padding for navigation bar .imePadding(), // padding for when IME appears onClick = { } ) { Icon(imageVector = Icons.Filled.Add, contentDescription = "Add") } } }
Şekil 1. IME animasyonları
Material 3 Bileşenleri için dahili destek
Kullanım kolaylığı sağlamak için yerleşik Material 3 composable'ların (androidx.compose.material3
)
tutamaçlarının birçoğu, composable'ların uygulamanıza Materyal özelliklerine göre nasıl yerleştirildiğine bağlı olarak kendiliğinden yerleşir.
Inset işleme composable'ları
Aşağıda, iç öğeleri otomatik olarak işleyen Malzeme Bileşenlerinin listesi verilmiştir.
Uygulama çubukları
TopAppBar
/SmallTopAppBar
/CenterAlignedTopAppBar
/MediumTopAppBar
/LargeTopAppBar
: Pencerenin üst kısmında kullanıldığı için sistem çubuklarının üst ve yatay kenarlarına dolgu olarak uygulanır.BottomAppBar
: Sistem çubuklarının alt ve yatay kenarlarını dolgu olarak uygular.
İçerik kapsayıcıları
ModalDrawerSheet
/DismissibleDrawerSheet
/PermanentDrawerSheet
(kalıcı gezinme çekmecesinin içindeki içerik): İçeriğe dikey ekler ve başlar.ModalBottomSheet
: Alt kümeler uygulanır.NavigationBar
: Alt ve yatay ekleri uygular.NavigationRail
: Sektör ve başlangıç eklerini uygular.
Yapı İskelesi
Varsayılan olarak Scaffold
, kullanmanız ve kullanmanız için paddingValues
parametresi olarak inset'ler sağlar.
Ekleri Scaffold
içeriği üzerinde uygulamaz; bu sorumluluk size aittir.
Örneğin, bu iç öğeleri Scaffold
içinde bir LazyColumn
ile kullanmak için:
Scaffold { innerPadding -> // innerPadding contains inset information for you to use and apply LazyColumn( // consume insets as scaffold doesn't do it by default modifier = Modifier.consumeWindowInsets(innerPadding), contentPadding = innerPadding ) { items(count = 100) { Box( Modifier .fillMaxWidth() .height(50.dp) .background(colors[it % colors.size]) ) } } }
Varsayılan iç öğeleri geçersiz kıl
composable'ın davranışını yapılandırmak için composable'a iletilen windowInsets
parametresini değiştirebilirsiniz. Bu parametre, bunun yerine uygulanacak farklı bir window inset türü olabilir veya boş bir örnek iletilerek devre dışı bırakılabilir: WindowInsets(0, 0, 0, 0)
.
Örneğin, LargeTopAppBar
üzerinde inset işlemesini devre dışı bırakmak için windowInsets
parametresini boş bir örneğe ayarlayın:
LargeTopAppBar( windowInsets = WindowInsets(0, 0, 0, 0), title = { Text("Hi") } )
View sistem setleriyle birlikte çalışma
Ekranınızda aynı hiyerarşide hem Görünümler hem de Oluşturma kodu olduğunda varsayılan ek öğeleri geçersiz kılmanız gerekebilir. Bu durumda, verinin hangi veride kullanıldığını, hangisinin hangi veriyi göz ardı etmesi gerektiğini net olarak belirlemeniz gerekir.
Örneğin, en dıştaki düzeniniz bir Android Görünümü düzeniyse ek öğeleri Görünüm sisteminde kullanmalı ve Oluştur için yoksaymalısınız.
Alternatif olarak, en dıştaki düzeniniz composable ise Compose'da içe aktarılan öğeleri kullanıp AndroidView
composable'ları buna uygun şekilde doldurmanız gerekir.
Varsayılan olarak her ComposeView
, WindowInsetsCompat
tüketim düzeyindeki tüm ekleri tüketir. Bu varsayılan davranışı değiştirmek için ComposeView.consumeWindowInsets
değerini false
olarak ayarlayın.
Kaynaklar
- Artık Android'de. Tamamen Kotlin ve Jetpack Compose ile geliştirilmiş, tamamen işlevsel bir Android uygulaması.
Sizin için önerilenler
- Not: Bağlantı metni JavaScript kapalıyken görüntülenir
- Malzeme Bileşenleri ve düzenler
CoordinatorLayout
öğesini Compose'a taşıyın- Dikkat edilmesi gereken diğer noktalar