Kullanıcı tarafından ölçeklendirilebilen içerikleri destekleme

Uygulamanızda ölçeklenebilir içeriği desteklemek için iki parmakla yakınlaştırma hareketlerini uygulayın. Bu, erişilebilirliği iyileştirmek için standart ve platformla tutarlı bir yöntemdir. Kullanıcıların metin ve kullanıcı arayüzü öğelerinin boyutunu ihtiyaçlarına göre sezgisel olarak ayarlamasına olanak tanır. Uygulamanız, ayrıntılı kontrol ve bağlamsal davranışla özel ölçeklendirme davranışı tanımlayabilir. Bu sayede, kullanıcıların genellikle ekran büyütme gibi sistem düzeyindeki bir özellikten daha hızlı keşfettiği bir deneyim sunulur.

Ölçeklendirme stratejisi seçme

Bu kılavuzda ele alınan stratejiler, kullanıcı arayüzünün ekranın genişliğine uyacak şekilde yeniden düzenlenmesine ve yeniden düzenlenmesine neden olur. Bu, yatay kaydırma ihtiyacını ve uzun metin satırlarını okumak için gereken can sıkıcı "zikzak" hareketini ortadan kaldırarak önemli bir erişilebilirlik avantajı sağlar.

Ek Okuma: Araştırmalar, az gören kullanıcılar için yeniden akışlı içeriğin, iki boyutlu kaydırma gerektiren arayüzlere göre önemli ölçüde daha okunabilir ve gezinmesi daha kolay olduğunu doğrulamaktadır. Daha fazla bilgi için Mobil Cihazlarda Kaydır ve Tara ile Yeniden Akıtılabilir İçerik Karşılaştırması başlıklı makaleyi inceleyin.

Tüm öğeleri veya yalnızca metin öğelerini ölçeklendirme

Aşağıdaki tabloda her bir ölçeklendirme stratejisinin görsel etkisi gösterilmektedir.

Strateji Yoğunluk ölçeklendirme Yazı tipi ölçeklendirme

Davranış

Her şeyi orantılı olarak ölçeklendirir. İçerik, kapsayıcısına sığacak şekilde yeniden düzenlenir. Böylece kullanıcının tüm içeriği görmek için yatay olarak kaydırması gerekmez.

Yalnızca metin öğelerini etkiler. Genel düzen ve metin dışı bileşenler aynı boyutta kalır.

Ölçeklenebilir olanlar

Tüm görsel öğeler: Metin, bileşenler (düğmeler, simgeler), resimler ve düzen boşlukları (dolgu, kenar boşlukları)

Yalnızca metin

Tanıtım

Öneriler

Görsel farklılıkları gördüğünüze göre, aşağıdaki tabloyu kullanarak avantaj ve dezavantajları değerlendirebilir ve içeriğiniz için en iyi stratejiyi seçebilirsiniz.

Kullanıcı arayüzü türü

Önerilen strateji

Muhakeme

Okuma odaklı düzenler

Örnekler: Haber makaleleri, mesajlaşma uygulamaları

Yoğunluk veya yazı tipi ölçeklendirme

Satır içi resimler de dahil olmak üzere tüm içerik alanını ölçeklendirmek için yoğunluk ölçeklendirme tercih edilir.

Yalnızca metnin ölçeklendirilmesi gerekiyorsa yazı tipi ölçeklendirme basit bir alternatiftir.

Görsel olarak yapılandırılmış düzenler

Örnekler: Uygulama mağazaları, sosyal medya feed'leri

Yoğunluk ölçekleme

Rulolarda veya tablolarda resimler ile metinler arasındaki görsel ilişkileri korur. Yeniden akış özelliği, iç içe yerleştirilmiş kaydırma öğeleriyle çakışacak yatay kaydırmayı önler.

Jetpack Compose'da ölçeklendirme hareketlerini algılama

Kullanıcı tarafından ölçeklendirilebilir içeriği desteklemek için önce çoklu dokunma hareketlerini algılamanız gerekir. Jetpack Compose'da bunu Modifier.transformable kullanarak yapabilirsiniz.

transformable değiştiricisi, son hareket etkinliğinden bu yana zoomChange farkını sağlayan üst düzey bir API'dir. Bu, durum güncelleme mantığını doğrudan birikime (ör. scale *= zoomChange) basitleştirerek bu kılavuzda ele alınan uyarlanabilir ölçeklendirme stratejileri için ideal hale getirir.

Pratiğe aktarma örnekleri

Aşağıdaki örneklerde, yoğunluk ölçeklendirme ve yazı tipi ölçeklendirme stratejilerinin nasıl uygulanacağı gösterilmektedir.

Yoğunluk ölçeklendirme

Bu yaklaşım, kullanıcı arayüzü alanının taban density değerini ölçeklendirir. Sonuç olarak, dolgu, boşluk ve bileşen boyutları dahil olmak üzere düzene dayalı tüm ölçümler, ekran boyutu veya çözünürlüğü değişmiş gibi ölçeklendirilir. Metin boyutu da yoğunluğa bağlı olduğundan orantılı olarak ölçeklendirilir. Bu strateji, belirli bir alandaki tüm öğeleri tek tip olarak büyütmek, kullanıcı arayüzünüzün genel görsel ritmini ve oranlarını korumak istediğinizde etkilidir.

private class DensityScalingState(
    // Note: For accessibility, typical min/max values are ~0.75x and ~3.5x.
    private val minScale: Float = 0.75f,
    private val maxScale: Float = 3.5f,
    private val currentDensity: Density
) {
    val transformableState = TransformableState { zoomChange, _, _ ->
        scaleFactor.floatValue =
            (scaleFactor.floatValue * zoomChange).coerceIn(minScale, maxScale)
    }
    val scaleFactor = mutableFloatStateOf(1f)
    fun scaledDensity(): Density {
        return Density(
            currentDensity.density * scaleFactor.floatValue,
            currentDensity.fontScale
        )
    }
}

@Composable
fun DensityScalingSample() {
    val currentDensity = LocalDensity.current
    val scaleState =
        remember(currentDensity) { DensityScalingState(currentDensity = currentDensity) }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .transformable(state = scaleState.transformableState),
        contentAlignment = Alignment.TopCenter
    ) {
        CompositionLocalProvider(
            LocalDensity provides scaleState.scaledDensity()
        ) {
            DemoCard()
        }
    }
}

Yazı tipi ölçeklendirme

Bu strateji daha hedef odaklıdır ve yalnızca fontScale faktörünü değiştirir. Sonuç olarak, yalnızca metin öğeleri büyür veya küçülürken kapsayıcılar, dolgu ve simgeler gibi diğer tüm düzen bileşenleri sabit boyutta kalır. Bu strateji, yoğun okuma yapılan uygulamalarda metin okunabilirliğini artırmak için idealdir.

class FontScaleState(
    // Note: For accessibility, typical min/max values are ~0.75x and ~3.5x.
    private val minScale: Float = 0.75f,
    private val maxScale: Float = 3.5f,
    private val currentDensity: Density
) {
    val transformableState = TransformableState { zoomChange, _, _ ->
        scaleFactor.floatValue =
            (scaleFactor.floatValue * zoomChange).coerceIn(minScale, maxScale)
    }
    val scaleFactor = mutableFloatStateOf(1f)
    fun scaledFont(): Density {
        return Density(
            currentDensity.density,
            currentDensity.fontScale * scaleFactor.floatValue
        )
    }
}

@Composable
fun FontScalingSample() {
    val currentDensity = LocalDensity.current
    val scaleState = remember { FontScaleState(currentDensity = currentDensity) }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .transformable(state = scaleState.transformableState),
        contentAlignment = Alignment.TopCenter
    ) {
        CompositionLocalProvider(
            LocalDensity provides scaleState.scaledFont()
        ) {
            DemoCard()
        }
    }
}

Paylaşılan demo kullanıcı arayüzü

Bu, farklı ölçeklendirme davranışlarını vurgulamak için önceki örneklerin her ikisi tarafından da kullanılan paylaşılan DemoCard composable'dır.

@Composable
private fun DemoCard() {
    Card(
        modifier = Modifier
            .width(360.dp)
            .padding(16.dp),
        shape = RoundedCornerShape(12.dp)
    ) {
        Column(
            modifier = Modifier.padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            Text("Demo Card", style = MaterialTheme.typography.headlineMedium)
            var isChecked by remember { mutableStateOf(true) }
            Row(verticalAlignment = Alignment.CenterVertically) {
                Text("Demo Switch", Modifier.weight(1f), style = MaterialTheme.typography.bodyLarge)
                Switch(checked = isChecked, onCheckedChange = { isChecked = it })
            }
            Row(verticalAlignment = Alignment.CenterVertically) {
                Icon(Icons.Filled.Person, "Icon", Modifier.size(32.dp))
                Spacer(Modifier.width(8.dp))
                Text("Demo Icon", style = MaterialTheme.typography.bodyLarge)
            }
            Row(
                Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween
            ) {
                Box(
                    Modifier
                        .width(100.dp)
                        .weight(1f)
                        .height(80.dp)
                        .background(Color.Blue)
                )
                Box(
                    Modifier
                        .width(100.dp)
                        .weight(1f)
                        .height(80.dp)
                        .background(Color.Red)
                )
            }
            Text(
                "Demo Text: Lorem ipsum dolor sit amet, consectetur adipiscing elit," +
                    " sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
                style = MaterialTheme.typography.bodyMedium,
                textAlign = TextAlign.Justify
            )
        }
    }
}

İpuçları ve dikkat edilmesi gereken noktalar

Daha iyi ve erişilebilir bir deneyim oluşturmak için aşağıdaki önerileri göz önünde bulundurun:

  • Hareketle yapılmayan ölçeklendirme kontrolleri sunmayı düşünün: Bazı kullanıcılar hareketleri kullanmakta zorlanabilir. Bu kullanıcıları desteklemek için hareketlere dayalı olmayan, ölçeği ayarlamanın veya sıfırlamanın alternatif bir yolunu sunabilirsiniz.
  • Tüm ölçekler için geliştirme yapın: Kullanıcı arayüzünüzü hem uygulama içi ölçeklendirmeye hem de sistem genelindeki yazı tipi veya görüntü ayarlarına göre test edin. Uygulamanızın düzenlerinin, içeriği bozmadan, üst üste bindirmeden veya gizli içerik oluşturmadan doğru şekilde uyarlandığından emin olun. Uyarlanabilir düzenler oluşturma hakkında daha fazla bilgi edinin.