Jetpack Compose আপনার অ্যাপের UI ডিজাইন ও তৈরি করার কাজকে অনেক সহজ করে দেয়। Compose নিম্নলিখিত উপায়ে স্টেটকে UI এলিমেন্টে ট্রান্সফর্ম করে:
- উপাদানের কম্পোজিশন
- এলিমেন্টের লেআউট
- উপাদান আঁকা
এই ডকুমেন্ট এলিমেন্টের লেআউটের উপর ফোকাস করে এবং আপনার UI এলিমেন্ট লেআউট করতে সাহায্য করার জন্য Compose-এর দেওয়া কিছু বিল্ডিং ব্লক ব্যাখ্যা করে।
Compose-এ লেআউটের লক্ষ্য
লেআউট সিস্টেমের Jetpack Compose প্রয়োগের দুটি প্রধান লক্ষ্য রয়েছে:
- উচ্চ পারফর্ম্যান্স
- সহজে কাস্টম লেআউট লেখার সুবিধা
কম্পোজেবল ফাংশনের প্রাথমিক বিষয়
কম্পোজেবল ফাংশন হল Compose-এর মূল উপাদান। কম্পোজ করার উপযুক্ত
ফাংশন হল এমন একটি ফাংশন যা Unit নির্গমন করে এবং আপনার UI-এর কোনও অংশ বর্ণনা করে। এই
ফাংশনটি কিছু ইনপুট নেয় এবং স্ক্রিনে যা দেখানো হয় তা তৈরি করে। কম্পোজ করার উপযুক্ত আইটেম সম্পর্কে আরও
তথ্য পেতে, Compose মেন্টাল
মডেল ডকুমেন্টেশন দেখুন।
একটি কম্পোজ করার উপযুক্ত ফাংশন একাধিক UI এলিমেন্ট এমিট করতে পারে। তবে, আপনি যদি সেগুলি কীভাবে সাজানো উচিত সেই বিষয়ে কোনও নির্দেশ না দেন, তাহলে Compose এলিমেন্টগুলিকে এমনভাবে সাজাতে পারে যা আপনার পছন্দ নাও হতে পারে। যেমন, এই কোড দুটি টেক্সট এলিমেন্ট জেনারেট করে:
@Composable fun ArtistCard() { Text("Alfred Sisley") Text("3 minutes ago") }
আপনি কীভাবে সেগুলি সাজাতে চান সেই বিষয়ে কোনও নির্দেশিকা না থাকলে, Compose টেক্সট এলিমেন্টগুলিকে একটির উপরে আরেকটি স্ট্যাক করে, ফলে সেগুলি আর পড়া যায় না:
Compose আপনাকে রেডি-টু-ইউজ লেআউটের একটি সংগ্রহ প্রদান করে যা আপনার UI এলিমেন্ট সাজাতে সাহায্য করে এবং এটি আপনার নিজস্ব, আরও বিশেষ লেআউটকে সহজে সংজ্ঞায়িত করে।
স্ট্যান্ডার্ড লেআউট কম্পোনেন্ট
অনেক ক্ষেত্রে, আপনি শুধু কম্পোজের স্ট্যান্ডার্ড লেআউট এলিমেন্ট ব্যবহার করতে পারবেন।
স্ক্রিনে আইটেম উল্লম্বভাবে প্লেস করতে
Column
ব্যবহার করুন।
@Composable fun ArtistCardColumn() { Column { Text("Alfred Sisley") Text("3 minutes ago") } }
একইভাবে, স্ক্রিনে আইটেমগুলি অনুভূমিকভাবে প্লেস করতে
Row
ব্যবহার করুন। Column ও Row, দু'টিই সেগুলিতে থাকা এলিমেন্টের অ্যালাইনমেন্ট কনফিগার করার
সুবিধা দেয়।
@Composable fun ArtistCardRow(artist: Artist) { Row(verticalAlignment = Alignment.CenterVertically) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { Text(artist.name) Text(artist.lastSeenOnline) } } }
একটি এলিমেন্টের উপরে আরেকটি এলিমেন্ট রাখতে Box ব্যবহার করুন। Box-এ থাকা এলিমেন্টগুলির নির্দিষ্ট অ্যালাইনমেন্ট কনফিগার করার সুবিধাও এতে আছে।
@Composable fun ArtistAvatar(artist: Artist) { Box { Image(bitmap = artist.image, contentDescription = "Artist image") Icon(Icons.Filled.Check, contentDescription = "Check mark") } }
প্রায়শই এইসব বিল্ডিং ব্লকই আপনার প্রয়োজন। আপনার অ্যাপের জন্য উপযুক্ত আরও বিস্তারিত লেআউট পেতে, আপনি এইসব লেআউট একত্রিত করার জন্য নিজের কম্পোজ করার উপযুক্ত ফাংশন লিখতে পারেন।
Row-এর মধ্যে সন্তানের পজিশন সেট করতে, horizontalArrangement এবং
verticalAlignment আর্গুমেন্ট সেট করুন। Column-এর জন্য, verticalArrangement এবং
horizontalAlignment আর্গুমেন্ট সেট করুন:
@Composable fun ArtistCardArrangement(artist: Artist) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.End ) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { /*...*/ } } }
লেআউট মডেল
লেআউট মডেলে, UI ট্রি একটি সিঙ্গেল পাসে লেআউট করা হয়। প্রতিটি নোডকে প্রথমে নিজেকে পরিমাপ করতে বলা হয়, তারপরে রিকার্সিভভাবে যেকোনও চাইল্ডকে পরিমাপ করতে বলা হয়, চাইল্ডদের কাছে সাইজ কনস্ট্রেন্ট পাস করে। তারপরে, লিফ নোডগুলির সাইজ পরিবর্তন করা হয় এবং সেগুলি প্লেস করা হয়, সমাধান করা সাইজ এবং প্লেসমেন্ট সংক্রান্ত নির্দেশাবলী ট্রিয়ের উপরের দিকে পাস করা হয়।
সংক্ষেপে, বাচ্চাদের আগে অভিভাবকের ছবি তোলা হয়, কিন্তু বাচ্চাদের পরে তাদের ছবি সাইজ ও প্লেস করা হয়।
নিচের SearchResult ফাংশনটি বিবেচনা করুন।
@Composable fun SearchResult() { Row { Image( // ... ) Column { Text( // ... ) Text( // ... ) } } }
এই ফাংশন নিম্নলিখিত UI ট্রি তৈরি করে।
SearchResult
Row
Image
Column
Text
Text
SearchResult উদাহরণে, UI ট্রি লেআউট এই ক্রম অনুসরণ করে:
- রুট নোড
Rowপরিমাপ করতে বলা হয়েছে। - রুট নোড
Rowতার প্রথম চাইল্ডImage-কে পরিমাপ করতে বলে। Imageহল একটি লিফ নোড (অর্থাৎ, এর কোনও চাইল্ড নোড নেই), তাই এটি একটি সাইজ রিপোর্ট করে এবং প্লেসমেন্ট সংক্রান্ত নির্দেশাবলী রিটার্ন করে।- রুট নোড
Rowতার দ্বিতীয় চাইল্ডColumn-কে পরিমাপ করতে বলে। Columnনোড তার প্রথমTextচাইল্ডকে পরিমাপ করতে বলে।- প্রথম
Textনোড হল একটি লিফ নোড, তাই এটি একটি সাইজ রিপোর্ট করে এবং প্লেসমেন্ট সংক্রান্ত নির্দেশাবলী ফেরত দেয়। Columnনোড তার দ্বিতীয়Textচাইল্ডকে পরিমাপ করতে বলে।- দ্বিতীয়
Textনোডটি হল লিফ নোড, তাই এটি একটি সাইজ রিপোর্ট করে এবং প্লেসমেন্ট সংক্রান্ত নির্দেশাবলী রিটার্ন করে। Columnনোড যেহেতু এর চাইল্ড নোড পরিমাপ, সাইজ ও প্লেস করেছে, তাই এটি নিজের সাইজ ও প্লেসমেন্ট নির্ধারণ করতে পারে।- এখন যেহেতু রুট নোড
Rowতার চাইল্ড নোড পরিমাপ, সাইজ ও প্লেস করেছে, তাই এটি নিজের সাইজ ও প্লেসমেন্ট নির্ধারণ করতে পারবে।
পারফর্ম্যান্স
Compose শুধুমাত্র একবার বাচ্চাদের পরিমাপ করে উচ্চ পারফর্ম্যান্স অর্জন করে। সিঙ্গেল-পাস মাপ পারফর্ম্যান্সের জন্য ভাল, এটি Compose-কে ডিপ UI ট্রি দক্ষতার সাথে ম্যানেজ করতে দেয়। কোনও এলিমেন্ট যদি তার চাইল্ডকে দু'বার পরিমাপ করে এবং সেই চাইল্ড যদি তার প্রতিটি চাইল্ডকে দু'বার পরিমাপ করে এবং এই প্রক্রিয়া চলতে থাকে, তাহলে সম্পূর্ণ UI লেআউট করার একটিমাত্র প্রচেষ্টাকে অনেক কাজ করতে হবে, যার ফলে আপনার অ্যাপের পারফর্ম্যান্স বজায় রাখা কঠিন হয়ে পড়বে।
কোনও কারণে আপনার লেআউটের জন্য একাধিক পরিমাপের প্রয়োজন হলে, Compose একটি বিশেষ সিস্টেম, অন্তর্নিহিত পরিমাপ অফার করে। আপনি এই ফিচার সম্পর্কে আরও জানতে Compose-এ অন্তর্নিহিত পরিমাপ লেআউট দেখুন।
যেহেতু পরিমাপ ও প্লেসমেন্ট লেআউট পাসের স্বতন্ত্র উপ-ফেজ, তাই কোনও পরিবর্তন যা শুধুমাত্র আইটেমের প্লেসমেন্টকে প্রভাবিত করে, পরিমাপকে নয়, তা আলাদাভাবে এক্সিকিউট করা যেতে পারে।
আপনার লেআউটে মডিফায়ার ব্যবহার করা
কম্পোজ মডিফায়ার নিবন্ধে আলোচনা করা হয়েছে, আপনার কম্পোজ করার উপযুক্ত আইটেমকে সাজাতে বা আরও উন্নত করতে আপনি
মডিফায়ার ব্যবহার করতে পারবেন। আপনার লেআউট কাস্টমাইজ করার জন্য
মডিফায়ার অপরিহার্য। যেমন, এখানে আমরা ArtistCard কাস্টমাইজ করতে
একাধিক মডিফায়ার চেইন করি:
@Composable fun ArtistCardModifiers( artist: Artist, onClick: () -> Unit ) { val padding = 16.dp Column( Modifier .clickable(onClick = onClick) .padding(padding) .fillMaxWidth() ) { Row(verticalAlignment = Alignment.CenterVertically) { /*...*/ } Spacer(Modifier.size(padding)) Card( elevation = CardDefaults.cardElevation(defaultElevation = 4.dp), ) { /*...*/ } } }
উপরের কোডে, একসাথে ব্যবহার করা বিভিন্ন মডিফায়ার ফাংশন লক্ষ্য করুন।
clickableব্যবহারকারীর ইনপুটের জন্য কম্পোজ করা যায় এমন প্রতিক্রিয়া তৈরি করে এবং রিপেল দেখায়।paddingকোনও এলিমেন্টের চারপাশে স্পেস তৈরি করে।fillMaxWidthকম্পোজ করার উপযুক্ত আইটেমকে এর পেরেন্ট থেকে পাওয়া সর্বাধিক প্রস্থে পূর্ণ করে।size()কোনও এলিমেন্টের পছন্দের প্রস্থ ও উচ্চতা নির্দিষ্ট করে।
স্ক্রল করা যায় এমন লেআউট
Compose জেসচার ডকুমেন্টেশন থেকে স্ক্রল করা যায় এমন লেআউট সম্পর্কে আরও জানুন।
তালিকা ও অলস তালিকার জন্য, কম্পোজ তালিকা সংক্রান্ত ডকুমেন্টেশন দেখুন।
রেসপন্সিভ লেআউট
বিভিন্ন স্ক্রিন ওরিয়েন্টেশন ও ফর্ম ফ্যাক্টর সাইজের কথা মাথায় রেখে লেআউট ডিজাইন করতে হবে। Compose-এ বিভিন্ন স্ক্রিন কনফিগারেশনের সাথে আপনার কম্পোজ করা যায় এমন লেআউট অ্যাডজাস্ট করার জন্য কয়েকটি মেকানিজম আগে থেকেই দেওয়া আছে।
সীমাবদ্ধতা
অভিভাবকের থেকে আসা সীমাবদ্ধতা সম্পর্কে জানতে এবং সেই অনুযায়ী লেআউট ডিজাইন করতে
আপনি BoxWithConstraints ব্যবহার করতে পারেন। কন্টেন্ট ল্যাম্বডার স্কোপে মাপ
সংক্রান্ত বিধিনিষেধ
দেখতে পাবেন। বিভিন্ন স্ক্রিন কনফিগারেশনের জন্য আলাদা আলাদা লেআউট কম্পোজ করতে, আপনি এইসব পরিমাপ সংক্রান্ত
বাধ্যবাধকতা ব্যবহার করতে পারবেন:
@Composable fun WithConstraintsComposable() { BoxWithConstraints { Text("My minHeight is $minHeight while my maxWidth is $maxWidth") } }
স্লট-ভিত্তিক লেআউট
UI তৈরি করা সহজ করতে, Compose Material
Design-এর উপর ভিত্তি করে
androidx.compose.material:material নির্ভরতা (Android Studio-তে Compose
প্রোজেক্ট তৈরি করার সময় অন্তর্ভুক্ত) সহ বিভিন্ন ধরনের কম্পোজ করার উপযুক্ত আইটেম প্রদান করে।
Drawer,
FloatingActionButton,
এবং TopAppBar-এর মতো এলিমেন্ট সবই প্রদান করা হয়েছে।
Material কম্পোনেন্ট স্লট API-এর প্রচুর ব্যবহার করে, এটি হল Compose-এর চালু করা একটি প্যাটার্ন
যা কম্পোজ করার উপযুক্ত আইটেমের উপরে কাস্টমাইজেশনের একটি লেয়ার নিয়ে আসে। এই পদ্ধতিতে
কম্পোনেন্ট আরও বেশি নমনীয় হয়ে ওঠে, কারণ এটি একটি চাইল্ড এলিমেন্ট গ্রহণ করে যা চাইল্ডের প্রতিটি কনফিগারেশন প্যারামিটারকে এক্সপোজ না করেই
নিজেকে কনফিগার করতে পারে।
স্লট, ডেভেলপারদের ইচ্ছামতো পূরণ করার জন্য UI-তে একটি ফাঁকা জায়গা ছেড়ে দেয়। যেমন, TopAppBar-এ আপনি এইসব স্লট কাস্টমাইজ করতে পারবেন:
কম্পোজ করার উপযুক্ত আইটেম সাধারণত content কম্পোজ করার উপযুক্ত ল্যাম্বডা ( content: @Composable
() -> Unit) নেয়। স্লট API নির্দিষ্ট ব্যবহারের জন্য একাধিক content প্যারামিটার এক্সপোজ করে।
যেমন, TopAppBar আপনাকে title,
navigationIcon ও actions-এর জন্য কন্টেন্ট প্রদান করতে দেয়।
যেমন,
Scaffold
আপনাকে সাধারণ মেটেরিয়াল ডিজাইন লেআউট স্ট্রাকচার সহ UI প্রয়োগ করতে দেয়।
Scaffoldসবচেয়ে সাধারণ টপ-লেভেল মেটেরিয়াল কম্পোনেন্টের জন্য স্লট প্রদান করে,
যেমন TopAppBar,
BottomAppBar,
FloatingActionButton,
এবং Drawer. Scaffold ব্যবহার করে, এইসব কম্পোনেন্ট সঠিকভাবে পজিশন করা হয়েছে কিনা এবং
একসাথে সঠিকভাবে কাজ করছে কিনা তা সহজেই নিশ্চিত করা যায়।
@Composable fun HomeScreen(/*...*/) { ModalNavigationDrawer(drawerContent = { /* ... */ }) { Scaffold( topBar = { /*...*/ } ) { contentPadding -> // ... } } }
আপনার জন্য সাজেস্ট করা হয়েছে
- মনে রাখবেন: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট দেখানো হয়
- কম্পোজ মডিফায়ার
- Jetpack Compose-এর জন্য Kotlin
- মেটেরিয়াল কম্পোনেন্ট ও লেআউট