از محتوای مقیاس‌پذیر کاربر پشتیبانی کنید

برای پشتیبانی از محتوای مقیاس‌پذیر در برنامه‌تان، اشاره‌های جمع کردن برای بزرگ‌نمایی را پیاده‌سازی کنید. این روش استاندارد و سازگار با پلاتفرم برای بهبود دسترس‌پذیری است و به کاربران امکان می‌دهد اندازه نوشتار و عناصر میانای کاربر را به‌طور شهودی متناسب با نیازهایشان تنظیم کنند. برنامه شما می‌تواند رفتار مقیاس‌بندی سفارشی را با کنترل دقیق و رفتار زمینه‌ای تعریف کند که تجربه‌ای را ارائه می‌دهد که کاربران اغلب سریع‌تر از ویژگی سطح سیستم مانند بزرگ‌نمایی صفحه کشف می‌کنند.

انتخاب استراتژی مقیاس‌بندی

استراتژی‌های پوشش‌داده‌شده در این راهنما باعث می‌شود واسط کاربر مجدداً جاری شود و برای متناسب شدن با پهنای صفحه سازماندهی شود. این ویژگی با ازبین بردن نیاز به حرکت افقی و حرکت زیگزاگی آزاردهنده که درغیراین‌صورت برای خواندن سطرهای طولانی نوشتار لازم است، مزیت دسترس‌پذیری قابل‌توجهی ارائه می‌دهد.

مطالعه بیشتر: پژوهش‌ها تأیید می‌کنند که برای کاربران کم‌بینا، جاری‌سازی مجدد محتوا به‌طور قابل‌توجهی خواناتر است و پیمایش آن آسان‌تر از واسط‌هایی است که به حرکت دوبعدی نیاز دارند. برای جزئیات بیشتر، مقایسه محتوای جاری‌شونده و محتوای اسکن و حرکت در دستگاه‌های همراه را ببینید.

همه عناصر یا فقط عناصر نوشتاری را مقیاس‌بندی کنید

جدول زیر جلوه تصویری هریک از استراتژی‌های مقیاس‌بندی را نشان می‌دهد.

استراتژی مقیاس‌بندی تراکم مقیاس‌بندی قلم

رفتار

همه چیز را به‌صورت متناسب مقیاس‌بندی می‌کند. محتوا جاری می‌شود تا دربرگیرنده خود جای بگیرد، بنابراین کاربر برای دیدن همه محتوا نیازی به پیمایش افقی ندارد.

فقط بر عناصر نوشتاری تأثیر می‌گذارد. چیدمان کلی و عناصر غیرمتنی در همان اندازه باقی می‌مانند.

چه چیزهایی مقیاس‌پذیر است

همه عناصر دیداری: نوشتار، عناصر (دکمه‌ها، نمادها)، تصاویر، و فاصله چیدمان (حاشیه، فاصله)

فقط نوشتار

تظاهرات

توصیه‌ها

اکنون که تفاوت‌های بصری را دیدید، جدول زیر به شما کمک می‌کند تا مبادله‌ها را بسنجید و بهترین استراتژی را برای محتوای خود انتخاب کنید.

نوع میانای کاربر

راهبرد توصیه‌شده

استدلال

چیدمان‌های خواندن‌محور

مثال‌ها: مقاله‌های خبری، برنامه‌های پیام‌رسانی

تراکم یا مقیاس‌بندی قلم

برای مقیاس‌بندی کل ناحیه محتوا، ازجمله تصاویر به‌خط، مقیاس‌بندی تراکم ترجیح داده می‌شود.

اگر فقط نوشتار نیاز به مقیاس‌بندی داشته باشد، مقیاس‌بندی قلم جایگزین ساده‌ای است.

چیدمان‌های ساختاریافته دیداری

مثال‌ها: فروشگاه‌های برنامه، فیدهای رسانه‌های اجتماعی

مقیاس‌بندی تراکم

روابط دیداری بین تصاویر و نوشتار را در گردونه‌ها یا شبکه‌ها حفظ می‌کند. ماهیت جاری‌سازی مجدد از حرکت افقی که با عناصر پیمایش تودرتو تداخل دارد جلوگیری می‌کند.

تشخیص اشاره‌های مقیاس‌بندی در Jetpack Compose

برای پشتیبانی از محتوای مقیاس‌پذیر کاربر، ابتدا باید اشاره‌های چندلمسی را تشخیص دهید. در Jetpack Compose، می‌توانید این کار را بااستفاده از Modifier.transformable انجام دهید.

اصلاح‌گر transformable یک API سطح بالا است که zoomChange دلتا را از آخرین رویداد اشاره ارائه می‌دهد. این کار منطق به‌روزرسانی وضعیت را به انباشت مستقیم (برای مثال، scale *= zoomChange) ساده می‌کند و آن را برای راهبردهای مقیاس‌بندی تطبیقی که در این راهنما پوشش داده شده است ایده‌آل می‌کند.

پیاده‌سازی‌های نمونه

مثال‌های زیر نحوه پیاده‌سازی استراتژی‌های مقیاس‌بندی تراکم و مقیاس‌بندی قلم را نشان می‌دهد.

مقیاس‌بندی تراکم

این رویکرد density پایه ناحیه واسط کاربر را مقیاس‌بندی می‌کند. در نتیجه، همه اندازه‌گیری‌های مبتنی بر چیدمان—ازجمله حاشیه، فاصله، و اندازه‌های عنصر—مقیاس‌بندی می‌شوند، انگار اندازه یا وضوح صفحه‌نمایش تغییر کرده است. چون اندازه نوشتار به تراکم نیز بستگی دارد، به‌صورت متناسب مقیاس‌بندی می‌شود. این استراتژی زمانی مؤثر است که بخواهید همه عناصر را در یک ناحیه خاص به‌طور یکنواخت بزرگ کنید و درعین‌حال ریتم بصری کلی و تناسب‌های رابط کاربری را حفظ کنید.

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()
        }
    }
}

مقیاس‌بندی قلم

این استراتژی هدفمندتر است و فقط عامل fontScale را تغییر می‌دهد. نتیجه این است که فقط عناصر نوشتاری بزرگ یا کوچک می‌شوند، درحالی‌که همه عناصر چیدمان دیگر—مثل محتوی‌ها، حاشیه، و نمادها—اندازه ثابتی دارند. این استراتژی برای بهبود خوانایی نوشتار در برنامه‌هایی که خواندن در آن‌ها اهمیت زیادی دارد مناسب است.

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()
        }
    }
}

واسط کاربر نمایشی هم‌رسانی‌شده

این DemoCard قابل‌ساخت مشترکی است که در هر دو مثال قبلی برای برجسته کردن رفتارهای مقیاس‌بندی مختلف استفاده شده است.

@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
            )
        }
    }
}

نکته‌ها و ملاحظات

برای ایجاد تجربه‌ای صیقلی‌تر و دردسترس‌تر، توصیه‌های زیر را درنظر بگیرید:

  • ارائه کنترل‌های مقیاس غیرژستی را درنظر بگیرید: برخی‌از کاربران ممکن است در استفاده از ژست‌ها مشکل داشته باشند. برای پشتیبانی از این کاربران، روش جایگزینی برای تنظیم یا بازنشانی مقیاس ارائه دهید که به اشاره‌ها وابسته نباشد.
  • ساختن برای همه مقیاس‌ها: واسط کاربر خود را دربرابر هر دو تنظیمات مقیاس‌بندی درون‌برنامه و قلم یا نمایش در سطح سیستم آزمایش کنید. بررسی کنید چیدمان‌های برنامه‌تان به‌درستی تطبیق داده شوند بدون اینکه محتوا شکسته شود، هم‌پوشانی داشته باشد، یا پنهان شود. درباره نحوه ساختن چیدمان‌های تطبیقی بیشتر بدانید.