ব্যবহারকারীর স্কেল করা যায় এমন কন্টেন্ট কাজ করে

আপনার অ্যাপে স্কেলেবল কন্টেন্টকে সাপোর্ট করতে পিঞ্চ-টু-জুম জেসচার প্রয়োগ করুন। অ্যাক্সেসিবিলিটি উন্নত করার জন্য এটি হল স্ট্যান্ডার্ড, প্ল্যাটফর্ম-কনসিস্টেন্ট পদ্ধতি, যা ব্যবহারকারীদের তাদের প্রয়োজন অনুযায়ী টেক্সট এবং UI এলিমেন্টের সাইজ স্বজ্ঞাতভাবে অ্যাডজাস্ট করতে দেয়। আপনার অ্যাপ গ্র্যানুলার কন্ট্রোল ও প্রাসঙ্গিক আচরণের মাধ্যমে কাস্টম স্কেলিং আচরণ নির্ধারণ করতে পারে যা এমন অভিজ্ঞতা প্রদান করে যা ব্যবহারকারীরা স্ক্রিন ম্যাগনিফিকেশনের মতো সিস্টেম-লেভেল ফিচারের চেয়ে আরও দ্রুত খুঁজে পান।

স্কেলিং স্ট্র্যাটেজি বেছে নিন

এই গাইডে কভার করা কৌশলগুলি UI-কে রিফ্লো এবং স্ক্রিনের প্রস্থের সাথে মানানসই করার জন্য পুনর্গঠন করে। এটি অনুভূমিক প্যানিং এবং হতাশাজনক "জিগ-জ্যাগ" মোশনের প্রয়োজনীয়তা দূর করে একটি উল্লেখযোগ্য অ্যাক্সেসিবিলিটি সুবিধা প্রদান করে যা অন্যথায় টেক্সটের দীর্ঘ লাইন পড়ার জন্য প্রয়োজন হবে।

আরও পড়ুন: রিসার্চ থেকে জানা গেছে যে স্বল্প দৃষ্টিশক্তি সম্পন্ন ব্যবহারকারীদের জন্য, রিফ্লোয়িং কন্টেন্ট, টু-ডাইমেনশনাল প্যানিং প্রয়োজন হয় এমন ইন্টারফেসের তুলনায় অনেক বেশি পাঠযোগ্য এবং নেভিগেট করা সহজ। আরও বিবরণের জন্য, মোবাইল ডিভাইসে প্যান-অ্যান্ড-স্ক্যান এবং রিফ্লোয়েবেল কন্টেন্টের তুলনা দেখুন।

সব এলিমেন্ট বা শুধু টেক্সট এলিমেন্ট স্কেল করুন

নিচের সারণীতে প্রতিটি স্কেলিং স্ট্র্যাটেজির ভিজ্যুয়াল এফেক্ট দেখানো হয়েছে।

স্ট্র্যাটেজি ডেনসিটি স্কেলিং ফন্ট স্কেলিং

আচরণ

সবকিছু আনুপাতিকভাবে স্কেল করে। কন্টেন্ট রিফ্লো করে কন্টেনারে ফিট করে, তাই ব্যবহারকারীকে সব কন্টেন্ট দেখার জন্য অনুভূমিকভাবে প্যান করতে হয় না।

শুধুমাত্র টেক্সট এলিমেন্টকে প্রভাবিত করে। সামগ্রিক লেআউট ও টেক্সট নয় এমন কম্পোনেন্ট একই সাইজের থাকে।

স্কেল কী

সব ভিজ্যুয়াল এলিমেন্ট: টেক্সট, কম্পোনেন্ট (বোতাম, আইকন), ছবি ও লেআউট স্পেসিং (প্যাডিং, মার্জিন)

শুধুমাত্র টেক্সট

প্রদর্শন

সাজেশন

এখন আপনি ভিজ্যুয়াল পার্থক্যগুলি দেখেছেন, নিম্নলিখিত টেবিলটি আপনাকে ট্রেড-অফগুলি বিবেচনা করতে এবং আপনার কন্টেন্টের জন্য সেরা স্ট্র্যাটেজি বেছে নিতে সাহায্য করবে।

UI-এর ধরন

সাজেস্ট করা স্ট্র্যাটেজি

Reasoning

পড়ার জন্য উপযুক্ত লেআউট

উদাহরণ: খবরের নিবন্ধ, মেসেজিং অ্যাপ

ঘনত্ব বা ফন্ট স্কেলিং

ইনলাইন ছবি সহ সম্পূর্ণ কন্টেন্ট এরিয়া স্কেল করার জন্য ডেনসিটি স্কেলিং ব্যবহার করা হয়।

শুধু টেক্সট স্কেল করতে হলে, ফন্ট স্কেলিং হল একটি সহজ বিকল্প।

ভিজ্যুয়ালি স্ট্রাকচার করা লেআউট

যেমন: অ্যাপ স্টোর, সোশ্যাল মিডিয়া ফিড

ঘনত্ব স্কেলিং

ক্যারোজেল বা গ্রিডে ছবি ও টেক্সটের মধ্যে ভিজ্যুয়াল সম্পর্ক বজায় রাখে। রিফ্লো করার প্রকৃতির কারণে অনুভূমিক প্যানিং এড়ানো যায়, যা নেস্টেড স্ক্রলিং এলিমেন্টের সাথে কনফ্লিক্ট করতে পারে।

Jetpack Compose-এ স্কেলিং জেসচার শনাক্ত করা

ব্যবহারকারী-স্কেলেবল কন্টেন্ট সাপোর্ট করতে, আপনাকে প্রথমে মাল্টি-টাচ জেসচার শনাক্ত করতে হবে। Jetpack Compose-এ, আপনি Modifier.transformable ব্যবহার করে এটি করতে পারবেন।

transformable মডিফায়ার হল একটি হাই-লেভেল API যা শেষ জেসচার ইভেন্টের পর থেকে zoomChange ডেল্টা প্রদান করে। এটি স্টেট আপডেট লজিককে সহজ করে তোলে সরাসরি অ্যাকুমুলেশন (যেমন, scale *= zoomChange), যা এই গাইডে কভার করা অ্যাডাপ্টিভ স্কেলিং স্ট্র্যাটেজির জন্য আদর্শ।

প্রয়োগের উদাহরণ

নিম্নলিখিত উদাহরণগুলি দেখায় যে কীভাবে ঘনত্ব স্কেলিং এবং ফন্ট স্কেলিং কৌশলগুলি বাস্তবায়ন করা যায়।

ডেনসিটি স্কেলিং

এই পদ্ধতি UI এলাকার বেস density স্কেল করে। এর ফলে, প্যাডিং, স্পেসিং ও কম্পোনেন্টের সাইজ সহ লেআউট-ভিত্তিক সব পরিমাপ স্কেল করা হয়, যেন স্ক্রিনের সাইজ বা রেজোলিউশন পরিবর্তন করা হয়েছে। টেক্সটের সাইজ ঘনত্বের উপর নির্ভর করে বলে এটিও আনুপাতিক হারে স্কেল করা হয়। এই স্ট্র্যাটেজিটি কার্যকরী হয় যখন আপনি একটি নির্দিষ্ট এলাকার মধ্যে সমস্ত উপাদানকে সমানভাবে বড় করতে চান, আপনার UI-এর সামগ্রিক ভিজ্যুয়াল ছন্দ এবং অনুপাত বজায় রেখে।

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

শেয়ার করা ডেমো UI

এটি হল শেয়ার করা 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
            )
        }
    }
}

পরামর্শ ও বিবেচনা

আরও পরিমার্জিত এবং অ্যাক্সেসযোগ্য অভিজ্ঞতা তৈরি করতে, নিম্নলিখিত সাজেশনগুলি বিবেচনা করুন:

  • জেসচার ছাড়া স্কেল কন্ট্রোল অফার করার কথা বিবেচনা করুন: কিছু ব্যবহারকারীর জেসচার ব্যবহার করতে সমস্যা হতে পারে। এইসব ব্যবহারকারীকে সাহায্য করার জন্য, স্কেল অ্যাডজাস্ট বা রিসেট করার জন্য বিকল্প কোনও উপায় প্রদান করার কথা বিবেচনা করুন যা জেসচারের উপর নির্ভর করে না।
  • সব স্কেলের জন্য তৈরি করুন: অ্যাপ-মধ্যস্থ স্কেলিং এবং সিস্টেম-ব্যাপী ফন্ট বা ডিসপ্লে সেটিংস, দুটির ক্ষেত্রেই আপনার UI পরীক্ষা করুন। আপনার অ্যাপের লেআউট কন্টেন্ট না ভেঙে, ওভারল্যাপ না করে বা না লুকিয়ে সঠিকভাবে মানিয়ে নিচ্ছে কিনা তা চেক করুন। কীভাবে অ্যাডাপ্টিভ লেআউট তৈরি করবেন সেই সম্পর্কে আরও জানুন।