Composable Function হল Jetpack Compose-এ ইউজার ইন্টারফেসের একটি মৌলিক একক যা নির্ধারণ করে যে স্ক্রিনের একটি অংশ কেমন দেখতে এবং আচরণ করবে। এই ধরনের প্রতিটি ফাংশন @Composable অ্যানোটেশন দিয়ে চিহ্নিত এবং একটি বিশেষ প্রসঙ্গে কার্যকর হয় যা Compose-কে নির্ভরতা ট্র্যাক করতে এবং ডেটা পরিবর্তনের সময় স্বয়ংক্রিয়ভাবে UI পুনর্নির্মাণ করতে দেয়। Google Android Developers, 2026 অনুসারে, Composable ফাংশনের সঠিক নির্মাণ সরাসরি অ্যাপ্লিকেশনের কর্মক্ষমতা এবং পুনর্গঠন দক্ষতাকে প্রভাবিত করে।
মূল পয়েন্ট
Composable Function হল Kotlin ভাষার একটি ফাংশন, @Composable অ্যানোটেশন দিয়ে চিহ্নিত, যা ঘোষণামূলক পদ্ধতিতে ইউজার ইন্টারফেসের একটি অংশ বর্ণনা করে। Java কোড বা XML মার্কআপের মাধ্যমে View অবজেক্ট তৈরি এবং কনফিগার করার পরিবর্তে, ডেভেলপার সহজভাবে লেখে যে ডেটার প্রতিটি অবস্থার জন্য UI কেমন দেখতে হবে।
Composable ফাংশন এবং传统的 Android View সিস্টেমের মধ্যে প্রধান পার্থক্য আপডেট মডেলে নিহিত। ক্লাসিক পদ্ধতিতে, ডেভেলপার ম্যানুয়ালি findViewById কল করত, setText-এর মাধ্যমে টেক্সট পরিবর্তন করত এবং setVisibility-এর মাধ্যমে দৃশ্যমানতা পরিচালনা করত। Composable Function আপনাকে এই রুটিন থেকে মুক্ত করে: যখন ডেটা পরিবর্তিত হয়, সিস্টেম নিজেই নির্ধারণ করে কোন ফাংশনগুলি পুনর্গঠন প্রয়োজন এবং শুধুমাত্র সেগুলি কার্যকর করে।
Kotlin কম্পাইলার, @Composable অ্যানোটেশন প্রক্রিয়াকরণ করে, অতিরিক্ত কোড তৈরি করে যা ফাংশনকে কম্পোজিশন মেকানিজমে সংহত করে। এই কোডের মধ্যে স্লটে পড়া এবং লেখা অন্তর্ভুক্ত — বিশেষ মেমরি সেল যা বর্তমান UI ট্রিতে প্রতিটি Composable ফাংশনের অবস্থা এবং প্যারামিটার সংরক্ষণ করে। এই সংহতকরণের জন্য ধন্যবাদ, Compose জানে কোন ফাংশন কোন ডেটার উপর নির্ভরশীল।
Composable ফাংশনের সিনট্যাক্স অত্যন্ত সংক্ষিপ্ত: শুধু fun কীওয়ার্ডের আগে @Composable যোগ করুন। ফাংশন যেকোনো প্যারামিটার গ্রহণ করতে পারে, তার বডিতে অন্যান্য Composable কল অন্তর্ভুক্ত করতে পারে এবং শর্তসাপেক্ষ UI রেন্ডারিংয়ের জন্য Kotlin নির্মাণ — শর্ত, লুপ, when-এক্সপ্রেশন — ব্যবহার করতে পারে।
@Composable
fun ProductItem(
product: Product,
modifier: Modifier = Modifier,
onAddToCart: () -> Unit
) {
Card(modifier = modifier.padding(8.dp)) {
Row(modifier = Modifier.fillMaxWidth().padding(12.dp),
verticalAlignment = Alignment.CenterVertically) {
Column(modifier = Modifier.weight(1f)) {
Text(text = product.name, style = MaterialTheme.typography.titleMedium)
Text(text = "${product.price}", color = MaterialTheme.colorScheme.primary)
}
Button(onClick = onAddToCart) {
Text("কার্টে যোগ করুন")
}
}
}
}
এই উদাহরণে, ProductItem Composable ফাংশন একটি Product অবজেক্ট, একটি মডিফায়ার এবং একটি কলব্যাক গ্রহণ করে। তিনটি প্যারামিটারই অপরিবর্তনীয়, যা পুনর্গঠনের সময় পূর্বানুমানযোগ্য আচরণ নিশ্চিত করে। মডিফায়ারটি একটি ডিফল্ট মান সহ প্যারামিটার হিসেবে পাস করা হয় — এটি একটি মানক অভ্যাস যা কলকারীকে প্যাডিং এবং আকার কাস্টমাইজ করতে দেয়।
Composable ফাংশনের ভিতরে, বিল্ট-ইন Material Design কম্পোনেন্ট (Text, Button, Card, TextField) বা মৌলিক প্রিমিটিভ (Canvas, Layout) ব্যবহার করা হয়। প্রতিটি কম্পোনেন্ট চেহারা এবং আচরণ কনফিগার করার জন্য প্যারামিটার গ্রহণ করে, পাশাপাশি modifier প্যারামিটারের মাধ্যমে এক বা একাধিক মডিফায়ার গ্রহণ করে।
মডিফায়ার হল ফাংশনের একটি চেইন যা কম্পোনেন্টের আকার, অবস্থান, ইভেন্ট হ্যান্ডলিং এবং চেহারা পরিবর্তন করে। চেইনে মডিফায়ারের ক্রম গুরুত্বপূর্ণ: clickable.semantics, semantics.clickable থেকে ভিন্নভাবে কাজ করে এবং padding.background প্যাডিং সহ এলাকা এবং পটভূমি উভয়ই রঙ করে, যা ডিজাইন করার সময় গুরুত্বপূর্ণ।
Composable ফাংশনের ভিতরে, আপনি শর্তসাপেক্ষ রেন্ডারিংয়ের জন্য if এবং when শর্ত ব্যবহার করতে পারেন, পাশাপাশি গতিশীল তালিকার জন্য for লুপ ব্যবহার করতে পারেন। এই সমস্ত নির্মাণ স্বাভাবিকভাবে কাজ করে কারণ Kotlin একটি পূর্ণাঙ্গ প্রোগ্রামিং ভাষা। তবে, এটি মনে রাখা গুরুত্বপূর্ণ: যদি একটি শর্ত বা লুপে Composable ফাংশন কল থাকে, সেগুলিও পুনর্গঠনে অংশগ্রহণ করে।
@Composable
fun ProductList(
products: List<Product>,
modifier: Modifier = Modifier
) {
LazyColumn(modifier = modifier) {
items(products, key = { it.id }) { product ->
ProductItem(
product = product,
onAddToCart = { /* add to cart */ }
)
}
}
}
আসুন একাধিক Composable ফাংশন ব্যবহার করে একটি পণ্য অনুসন্ধান স্ক্রিনের উদাহরণ বিবেচনা করি। এখানে সাধারণ প্যাটার্ন দেখানো হয়েছে: অবস্থাসহ ইনপুট ফিল্ড, তালিকা ফিল্টারিং, খালি ফলাফল হ্যান্ডলিং এবং লোডিং।
data class Product(
val id: String,
val name: String,
val price: Double,
val category: String
)
@Composable
fun SearchScreen() {
var query by remember { mutableStateOf("") }
val products = remember(query) { getFilteredProducts(query) }
Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
OutlinedTextField(
value = query,
onValueChange = { query = it },
label = { Text("পণ্য অনুসন্ধান করুন") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
when (products) {
is Loading -> CircularProgressIndicator()
is Empty -> Text("কোনো ফলাফল পাওয়া যায়নি")
is Result -> LazyColumn {
items(products.items, key = { it.id }) { product ->
ProductItem(product = product, onAddToCart = {})
}
}
}
}
}
এই উদাহরণটি একসাথে বেশ কয়েকটি আইডিয়ম প্রদর্শন করে: অনুসন্ধান কোয়েরির অবস্থা সংরক্ষণের জন্য remember, কী দিয়ে ফিল্টার করার জন্য remember(query), তিনটি UI অবস্থার জন্য when এবং দক্ষ তালিকা রেন্ডারিংয়ের জন্য LazyColumn। এই প্রতিটি আইডিয়ম Compose অ্যাপ্লিকেশন ডেভেলপ করার ব্যবহারিক অভিজ্ঞতার ফলাফল।
Composable ফাংশন সাধারণ Kotlin ফাংশনের মতোই প্যারামিটার গ্রহণ করে, তবে একটি গুরুত্বপূর্ণ পার্থক্যের সাথে: একটি প্যারামিটার @Composable অ্যানোটেশনসহ lambda-এর মাধ্যমে পাস করা অন্য Composable ফাংশন হতে পারে। এই মেকানিজমকে Slot API বলা হয় এবং এটি পুনর্ব্যবহারযোগ্য কন্টেইনার তৈরির প্রধান প্যাটার্ন।
Slot API সেই সমস্যার সমাধান করে যা传统的 View সিস্টেমে ViewGroup এবং প্রোগ্রামেটিকভাবে চাইল্ড View যোগ করার মাধ্যমে সমাধান করা হত। addView পদ্ধতির পরিবর্তে, Compose content lambda ব্যবহার করে — @Composable () -> Unit টাইপের শেষ প্যারামিটার। কলকারী এই lambda-তে যেকোনো UI পাস করে এবং কন্টেইনার শুধুমাত্র তার লেআউট নির্ধারণ করে।
Composable ফাংশনের প্যারামিটারের ডিফল্ট মান থাকতে পারে, যা বিভিন্ন প্রসঙ্গে তাদের ব্যবহার সহজ করে। সুপারিশ করা হয় শুধুমাত্র সেই প্যারামিটারগুলিকে বাধ্যতামূলক করা যেগুলি ছাড়া ফাংশন তার কাজ সম্পাদন করতে পারে না এবং বাকিগুলির জন্য যুক্তিসঙ্গত ডিফল্ট মান প্রদান করা।
| প্যারামিটার | টাইপ | উদাহরণ |
|---|---|---|
| বাধ্যতামূলক | যেকোনো টাইপ | name: String |
| ঐচ্ছিক | ডিফল্ট মান সহ | modifier: Modifier = Modifier |
| Content | @Composable () -> Unit | content: @Composable () -> Unit |
| Callback | @Composable ছাড়া Lambda | onClick: () -> Unit |
Compose কমিউনিটিতে বেশ কয়েকটি প্রতিষ্ঠিত আইডিয়ম আবির্ভূত হয়েছে যা Composable ফাংশনকে আরও পঠনযোগ্য এবং পূর্বানুমানযোগ্য করে তোলে। প্রথমটি হল State Hoisting: অবস্থা উচ্চ স্তরে উত্তোলন করা হয় এবং Composable ফাংশন এটি প্যারামিটারের মাধ্যমে গ্রহণ করে। এটি ফাংশনকে বিশুদ্ধ এবং বিভিন্ন প্রসঙ্গে পুনর্ব্যবহারযোগ্য করে তোলে।
দ্বিতীয় আইডিয়ম হল Event-driven প্যারামিটার। Composable ফাংশনে ViewModel বা useCase পাস করার পরিবর্তে, শুধুমাত্র নির্দিষ্ট কলব্যাক পাস করা হয়: onSave, onDelete, onNavigateToDetail। এটি যুগ্মতা হ্রাস করে এবং পরীক্ষা সহজ করে — ProductItem-এর পরীক্ষার জন্য ViewModel-এর প্রয়োজন নেই, শুধুমাত্র একটি lambda স্টাব।
তৃতীয় আইডিয়ম হল CompositionLocal কম্পোজিশন ট্রির মাধ্যমে শেয়ার্ড ডেটা পাস করার জন্য। থিম, স্ক্রিন ঘনত্ব, বর্তমান Route — এই সব CompositionLocal-এর মাধ্যমে পাস করা হয়, কয়েক ডজন Composable ফাংশনের মাধ্যমে প্যারামিটার চেইন এড়িয়ে। তবে, CompositionLocal-এর অতিরিক্ত ব্যবহার করা উচিত নয়: স্পষ্ট প্যারামিটার সবসময় অন্তর্নিহিত নির্ভরতার চেয়ে ভাল।
// State Hoisting: অবস্থা প্যারেন্ট ফাংশনে উত্তোলিত
@Composable
fun CounterDisplay(
count: Int,
onIncrement: () -> Unit
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "কাউন্টার: $count", style = MaterialTheme.typography.headlineLarge)
Button(onClick = onIncrement) {
Text("+1")
}
}
}
// State Hoisting-এর সাথে ব্যবহার
@Composable
fun CounterScreen() {
var count by remember { mutableStateOf(0) }
CounterDisplay(
count = count,
onIncrement = { count++ }
)
}
সচরাচর জিজ্ঞাসিত প্রশ্ন
হ্যাঁ, return অনুমোদিত, কিন্তু সতর্কতার সাথে। Compose পৃথক ফাংশনের স্তরে পুনর্গঠন অপ্টিমাইজ করে এবং তাড়াতাড়ি return এই অপ্টিমাইজেশন ভাঙতে পারে। ফাংশনের বডির ভিতরে শর্তসাপেক্ষ অপারেটর if বা when ব্যবহার করা ভাল।
Kotlin-এ, Unit হল একটি সিংগলটন অবজেক্ট, খালি টাইপ নয়। Composable ফাংশন Unit রিটার্ন করে, যা প্রযুক্তিগতভাবে অর্থ হল তারা নিজেই Unit অবজেক্ট রিটার্ন করে। তবে, অনুশীলনে এটি গুরুত্বপূর্ণ নয় — রিটার্ন মান কম্পোজিশন সিস্টেম দ্বারা উপেক্ষা করা হয়।
পরিবর্তনযোগ্য কালেকশন পাস করা সম্ভব, কিন্তু এটি খারাপ অভ্যাস। যদি কালেকশন পরিবর্তিত হয়, Compose এটি সম্পর্কে জানবে না কারণ অবজেক্ট রেফারেন্স একই থাকে। ট্র্যাক করা পরিবর্তনের জন্য অপরিবর্তনীয় তালিকা বা mutableStateListOf ব্যবহার করুন।
ডিবাগিংয়ের জন্য, Layout Inspector-সহ Android Studio ব্যবহার করুন, যা বর্তমান Composable ফাংশন ট্রি, প্যারামিটার মান এবং পুনর্গঠনের কারণ দেখায়। সাধারণ Kotlin ডিবাগারও কাজ করে — Composable ফাংশনের ভিতরে ব্রেকপয়েন্ট প্রতিটি পুনর্গঠনে সঠিকভাবে সক্রিয় হয়।
Composable ফাংশন সর্বদা Unit রিটার্ন করে, তাই রিটার্ন টাইপ নির্দিষ্ট করা হয় না। অন্য টাইপ রিটার্ন করার চেষ্টা কম্পাইলেশন ত্রুটির কারণ হবে কারণ @Composable অ্যানোটেশন নন-Unit রিটার্ন টাইপের সাথে অসঙ্গত।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন