Pencere içe eklemelerini ayarlama

Uygulamanızın içeriği nereye çizeceği üzerinde tam kontrol sahibi olmasını sağlamak için aşağıdaki kurulum adımlarını uygulayın. Bu adımlar uygulanmadığı takdirde uygulamanız, sistem kullanıcı arayüzünün arkasında siyah veya düz renkler çizebilir ya da yazılım klavyesiyle eşzamanlı olarak animasyon oluşturmayabilir.

  1. Android 15 ve sonraki sürümlerde uçtan uca görünümü zorunlu kılmak için Android 15'i (API düzeyi 35) veya sonraki sürümleri hedefleyin. Uygulamanız, sistem kullanıcı arayüzünün arkasında gösteriliyor. Uygulamanızın kullanıcı arayüzünü, dolguları işleyerek ayarlayabilirsiniz.
  2. İsteğe bağlı olarak, enableEdgeToEdge()Activity.onCreate() içinde çağırın. Bu, uygulamanızın önceki Android sürümlerinde uçtan uca olmasını sağlar.
  3. Etkinliğinizin android:windowSoftInputMode="adjustResize" girişinde AndroidManifest.xml simgesini ayarlayın. Bu ayar, uygulamanızın yazılım IME'sinin boyutunu yerleşim olarak almasına olanak tanır. Bu sayede, IME uygulamanızda göründüğünde ve kaybolduğunda uygun düzeni ve dolguyu uygulayabilirsiniz.

    <!-- 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">
    

Compose API'lerini kullanma

Etkinliğiniz tüm yerleştirmeleri işleme almayı kontrol ettikten sonra, içeriğin gizlenmemesini ve etkileşimli öğelerin sistem kullanıcı arayüzüyle çakışmamasını sağlamak için Compose API'lerini kullanabilirsiniz. Bu API'ler, uygulamanızın düzenini yerleştirme değişiklikleriyle de senkronize eder.

Örneğin, dolguları uygulamanızın tamamındaki içeriğe uygulamanın en temel yöntemi şudur:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    enableEdgeToEdge()

    setContent {
        Box(Modifier.safeDrawingPadding()) {
            // the rest of the app
        }
    }
}

Bu snippet, safeDrawing pencere içlerini uygulamanın tüm içeriğinin etrafında dolgu olarak uygular. Bu, etkileşimli öğelerin sistem kullanıcı arayüzüyle çakışmamasını sağlarken uygulamanın hiçbir bölümünün uçtan uca efekt elde etmek için sistem kullanıcı arayüzünün arkasında çizilmeyeceği anlamına da gelir. Pencerenin tamamından yararlanmak için iç kısımların ekrana veya bileşene göre ayrı ayrı uygulanacağı yerleri hassas bir şekilde ayarlamanız gerekir.

Bu ekleme türlerinin tümü, API 21'e geri aktarılan IME animasyonlarıyla otomatik olarak animasyonlu hale getirilir. Bununla birlikte, bu iç kısımları kullanan tüm düzenleriniz de iç kısım değerleri değiştikçe otomatik olarak animasyonlu hale gelir.

Bu yerleştirme türlerini kullanarak Composable düzenlerinizi ayarlamanın iki temel yolu vardır: dolgu değiştiriciler ve yerleştirme boyutu değiştiriciler.

Dolgu değiştiriciler

Modifier.windowInsetsPadding(windowInsets: WindowInsets), Modifier.padding gibi davranarak verilen pencere içlerini dolgu olarak uygular. Örneğin, Modifier.windowInsetsPadding(WindowInsets.safeDrawing), güvenli çizim içlerini 4 tarafın tamamında dolgu olarak uygular.

En yaygın yerleştirme türleri için çeşitli yerleşik yardımcı yöntemler de vardır. Modifier.safeDrawingPadding(), Modifier.windowInsetsPadding(WindowInsets.safeDrawing) değerine eş değer olan yöntemlerden biridir. Diğer içe yerleştirme türleri için benzer değiştiriciler vardır.

İç kısım boyutu değiştiricileri

Aşağıdaki değiştiriciler, bileşenin boyutunu iç kısımların boyutu olarak ayarlayarak bir pencere iç kısmı miktarı uygular:

Modifier.windowInsetsStartWidth(windowInsets: WindowInsets)

windowInsets'in başlangıç tarafını genişlik olarak uygular (ör. Modifier.width).

Modifier.windowInsetsEndWidth(windowInsets: WindowInsets)

windowInsets'in son tarafını genişlik olarak uygular (ör. Modifier.width)

Modifier.windowInsetsTopHeight(windowInsets: WindowInsets)

windowInsets'in üst tarafını yükseklik olarak uygular (ör. Modifier.height)

Modifier.windowInsetsBottomHeight(windowInsets: WindowInsets)

windowInsets'in alt tarafını yükseklik olarak uygular (ör. Modifier.height).

Bu değiştiriciler, özellikle iç kısımların alanını kaplayan bir Spacer boyutlandırmak için yararlıdır:

LazyColumn(
    Modifier.imePadding()
) {
    // Other content
    item {
        Spacer(
            Modifier.windowInsetsBottomHeight(
                WindowInsets.systemBars
            )
        )
    }
}

İçe doğru tüketim

İç dolgu değiştiriciler (windowInsetsPadding ve safeDrawingPadding gibi yardımcılar), dolgu olarak uygulanan iç kısımların bir bölümünü otomatik olarak kullanır. Kompozisyon ağacında daha derine inerken, iç içe yerleştirilmiş inset padding değiştiricileri ve inset boyutu değiştiricileri, insetlerin bir kısmının zaten dıştaki inset padding değiştiricileri tarafından kullanıldığını bilir ve insetlerin aynı kısmını birden fazla kez kullanmaktan kaçınır. Aksi takdirde çok fazla ek alan oluşur.

İç kısım boyutu değiştiriciler, iç kısımlar zaten kullanılmışsa aynı iç kısım bölümünün birden fazla kez kullanılmasını da önler. Ancak boyutlarını doğrudan değiştirdikleri için kendileri iç kenar kullanmazlar.

Bu nedenle, iç içe yerleştirilmiş dolgu değiştiriciler, her composable'a uygulanan dolgu miktarını otomatik olarak değiştirir.

Daha önceki LazyColumn örneğine baktığımızda, LazyColumn öğesinin imePadding değiştiricisi tarafından yeniden boyutlandırıldığını görüyoruz. LazyColumn içinde, son öğe sistem çubuklarının alt kısmının yüksekliğinde 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, iç kısımlar kullanılmaz ve Spacer öğesinin yüksekliği, sistem çubuklarının alt tarafının boyutu olur.

IME açıldığında, IME ekleri IME'nin boyutuna uyacak şekilde animasyonlu olarak değişir ve imePadding() değiştiricisi, IME açılırken imePadding() öğesini yeniden boyutlandırmak için alt dolgu uygulamaya başlar.LazyColumn imePadding() değiştiricisi imePadding() alt dolguyu uygulamaya başladığında, bu miktarda iç boşluğu da kullanmaya başlar. Bu nedenle, sistem çubuklarının aralığı için imePadding() değiştiricisi tarafından zaten aralık uygulandığından 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 kapandığında değişiklikler tersine gerçekleşir: Spacer, imePadding() sistem çubuklarının alt tarafının daha azını uyguladığında sıfır yüksekliğinden başlayarak genişlemeye başlar. Son olarak, IME tamamen animasyonla kapatıldığında Spacer, sistem çubuklarının alt tarafının yüksekliğiyle eşleşir.

Şekil 2. TextField ile uçtan uca tembel sütun.

Bu davranış, tüm windowInsetsPadding değiştiricileri arasındaki iletişimle sağlanır ve birkaç farklı şekilde etkilenebilir.

Modifier.consumeWindowInsets(insets: WindowInsets), Modifier.windowInsetsPadding ile aynı şekilde ekleri kullanır ancak kullanılan ekleri dolgu olarak uygulamaz. Bu özellik, kardeşlere belirli bir miktar iç boşluğun zaten kullanıldığını belirtmek için iç boşluk boyutu değiştiricileriyle birlikte kullanışlı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şkeni olan sürümle çok benzer şekilde davranır ancak tüketmek için rastgele bir PaddingValues alır. Bu, iç dolgu değiştiriciler dışında başka bir mekanizma (ör. normal Modifier.padding veya sabit yükseklikteki ayırıcılar) tarafından dolgu veya aralık sağlandığında çocukları bilgilendirmek için kullanışlıdır:

Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) {
    // content
    Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
}

Ham pencere yerlerinin tüketim olmadan gerekli olduğu durumlarda, WindowInsets değerlerini doğrudan kullanın veya tüketimden etkilenmeyen yerlerin PaddingValues değerini döndürmek için WindowInsets.asPaddingValues() kullanın. Ancak aşağıdaki uyarılar nedeniyle mümkün olduğunda pencere iç boşlukları dolgu değiştiricilerini ve pencere iç boşlukları boyutu değiştiricilerini kullanmayı tercih edin.

İç boşluklar ve Jetpack Compose aşamaları

Compose, ekleri güncellemek ve animasyon eklemek için temel AndroidX çekirdek API'lerini kullanır. Bu API'ler, ekleri yöneten temel platform API'lerini kullanır. Bu platform davranışı nedeniyle, dolgular Jetpack Compose'un aşamalarıyla özel bir ilişkiye sahiptir.

İç boşlukların değeri, kompozisyon aşamasından sonra ancak düzen aşamasından önce güncellenir. Bu, kompozisyondaki iç kısımların değerinin okunmasının genellikle bir kare gecikmeli bir iç kısım değeri kullandığı anlamına gelir. Bu sayfada açıklanan yerleşik değiştiriciler, yerleştirme değerlerinin düzen aşamasına kadar kullanılmasını geciktirmek için tasarlanmıştır. Bu sayede, yerleştirme değerlerinin güncellendikleri karede kullanılmaları sağlanır.