আপনার অ্যাপে স্কেলেবল কন্টেন্ট কাজ করার জন্য পিঞ্চ-টু-জুম জেসচার প্রয়োগ করুন। এটি অ্যাক্সেসিবিলিটি উন্নত করার একটি স্ট্যান্ডার্ড, প্ল্যাটফর্ম-কনসিস্টেন্ট পদ্ধতি। এর মাধ্যমে ব্যবহারকারীরা স্বজ্ঞাতভাবে টেক্সট ও UI এলিমেন্টের সাইজ অ্যাডজাস্ট করে তাদের প্রয়োজন অনুযায়ী করে নিতে পারেন। আপনার অ্যাপ, গ্র্যানুলার কন্ট্রোল ও প্রাসঙ্গিক আচরণের মাধ্যমে কাস্টম স্কেলিং আচরণকে সংজ্ঞায়িত করতে পারে যা এমন অভিজ্ঞতা প্রদান করে যা ব্যবহারকারীরা প্রায়শই স্ক্রিন ম্যাগনিফিকেশনের মতো সিস্টেম-লেভেল ফিচারের চেয়ে বেশি দ্রুত ডিসকভার করেন।
স্কেলিং স্ট্র্যাটেজি বেছে নিন
এই নির্দেশিকায় বর্ণিত কৌশলগুলি UI-কে রিফ্লো এবং রিঅর্গানাইজ করে স্ক্রিনের প্রস্থের সাথে ফিট করে। এটি অনুভূমিক প্যানিং এবং বিরক্তিকর "জিগ-জ্যাগ" মোশন এর প্রয়োজনীয়তা দূর করে উল্লেখযোগ্য অ্যাক্সেসিবিলিটি সুবিধা প্রদান করে যা অন্যথায় টেক্সটের দীর্ঘ লাইন পড়ার জন্য প্রয়োজন হত।
আরও পড়ুন: গবেষণা থেকে জানা গেছে যে, স্বল্প দৃষ্টিশক্তি সম্পন্ন ব্যবহারকারীদের জন্য, রিফ্লো করা কন্টেন্ট, টু-ডাইমেনশনাল প্যানিংয়ের প্রয়োজন হয় এমন ইন্টারফেসের তুলনায় অনেক বেশি পাঠযোগ্য এবং নেভিগেট করা সহজ। আরও বিবরণের জন্য, মোবাইল ডিভাইসে প্যান-অ্যান্ড-স্ক্যান ও রিফ্লোয়েবল কন্টেন্টের তুলনা দেখুন।
সব এলিমেন্ট বা শুধুমাত্র টেক্সট এলিমেন্ট স্কেল করা
নিচের সারণীতে প্রতিটি স্কেলিং স্ট্র্যাটেজির ভিজ্যুয়াল এফেক্ট দেখানো হয়েছে।
| স্ট্র্যাটেজি | ঘনত্ব স্কেলিং | ফন্ট স্কেলিং |
|---|---|---|
আচরণ |
সবকিছু সমান অনুপাতে স্কেল করে। কন্টেন্টটি কন্টেনারের সাথে মানানসই করে রিফ্লো করা হয়, তাই ব্যবহারকারীকে সমস্ত কন্টেন্ট দেখতে অনুভূমিকভাবে প্যান করতে হয় না। |
শুধুমাত্র টেক্সট এলিমেন্টের উপর প্রভাব ফেলে। সামগ্রিক লেআউট ও টেক্সট ছাড়া অন্যান্য কম্পোনেন্ট একই সাইজের থাকে। |
কী কী স্কেল |
সব ভিজ্যুয়াল এলিমেন্ট: টেক্সট, কম্পোনেন্ট (বোতাম, আইকন), ছবি ও লেআউট স্পেসিং (প্যাডিং, মার্জিন) |
শুধুমাত্র টেক্সট |
ডেমোনস্ট্রেশন |
সাজেশন
আপনি যেহেতু ভিজ্যুয়াল পার্থক্য দেখেছেন, তাই নিম্নলিখিত টেবিলটি আপনাকে ট্রেড-অফ ওজন করতে এবং আপনার কন্টেন্টের জন্য সেরা কৌশল বেছে নিতে সাহায্য করে।
UI-এর ধরন |
সাজেস্ট করা স্ট্র্যাটেজি |
যুক্তি |
পঠন-নির্ভর লেআউট যেমন: খবরের নিবন্ধ, মেসেজিং অ্যাপ |
ঘনত্ব বা ফন্ট স্কেলিং |
ইনলাইন ছবি সহ সম্পূর্ণ কন্টেন্ট এরিয়া স্কেল করার জন্য ডেনসিটি স্কেলিং ব্যবহার করা হয়। শুধুমাত্র টেক্সট স্কেল করার প্রয়োজন হলে, ফন্ট স্কেলিং হল একটি সহজ বিকল্প। |
ভিজ্যুয়ালি স্ট্রাকচার করা লেআউট যেমন: অ্যাপ স্টোর, সোশ্যাল মিডিয়া ফিড |
ঘনত্ব স্কেলিং |
ক্যারোজেল বা গ্রিডে ছবি ও টেক্সটের মধ্যে ভিজ্যুয়াল সম্পর্ক বজায় রাখে। রিফ্লো করার সুবিধা থাকার ফলে হরাইজন্টাল প্যানিং এড়ানো যায়, যা নেস্ট করা স্ক্রলিং এলিমেন্টের সাথে কনফ্লিক্ট তৈরি করতে পারে। |
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-কে ইন-অ্যাপ স্কেলিং ও সিস্টেম-ব্যাপী ফন্ট বা ডিসপ্লে সেটিংসের বিরুদ্ধে পরীক্ষা করুন। আপনার অ্যাপের লেআউট যাতে কন্টেন্ট ভেঙে, ওভারল্যাপ বা লুকিয়ে না ফেলে সেই জন্য সঠিকভাবে অ্যাডাপ্ট করে তা চেক করুন। অ্যাডাপ্টিভ লেআউট কীভাবে তৈরি করতে হয় সেই সম্পর্কে আরও জানুন।