লেআউট বেসিক রচনা করুন

Jetpack Compose আপনার অ্যাপের UI ডিজাইন ও তৈরি করা অনেক সহজ করে তোলে। Compose নিম্নলিখিত উপায়ে স্টেটকে UI এলিমেন্টে রূপান্তরিত করে:

  1. উপাদানের গঠন
  2. উপাদানগুলির বিন্যাস
  3. উপাদানগুলির অঙ্কন

কম্পোজিশন, লেআউট, ড্রয়িং-এর মাধ্যমে স্টেটকে UI-তে রূপান্তর করা।

এই ডকুমেন্টটি এলিমেন্টগুলোর বিন্যাসের উপর আলোকপাত করে এবং আপনার UI এলিমেন্টগুলো সাজাতে সাহায্য করার জন্য Compose-এর দেওয়া কিছু মৌলিক উপাদান ব্যাখ্যা করে।

কম্পোজে লেআউটের লক্ষ্যসমূহ

জেটপ্যাক কম্পোজ-এর লেআউট সিস্টেম বাস্তবায়নের দুটি প্রধান লক্ষ্য রয়েছে:

কম্পোজেবল ফাংশনের মূল বিষয়াবলী

কম্পোজেবল ফাংশন হলো কম্পোজ-এর মূল ভিত্তি। একটি কম্পোজেবল ফাংশন হলো এমন একটি ফাংশন যা Unit নির্গত করে এবং আপনার UI-এর কোনো অংশ বর্ণনা করে। ফাংশনটি কিছু ইনপুট গ্রহণ করে এবং স্ক্রিনে যা দেখানো হয় তা তৈরি করে। কম্পোজেবল সম্পর্কে আরও তথ্যের জন্য, কম্পোজ মেন্টাল মডেল ডকুমেন্টেশনটি দেখুন।

একটি কম্পোজেবল ফাংশন একাধিক 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 ট্রি লেআউটটি এই ক্রম অনুসরণ করে:

  1. রুট নোড Row পরিমাপ করতে বলা হয়েছে।
  2. রুট নোড Row তার প্রথম চাইল্ড, Image পরিমাপ করতে বলে।
  3. Image একটি লিফ নোড (অর্থাৎ, এর কোনো চাইল্ড নেই), তাই এটি একটি সাইজ রিপোর্ট করে এবং প্লেসমেন্টের নির্দেশনা রিটার্ন করে।
  4. রুট নোড Row তার দ্বিতীয় চাইল্ড, Column পরিমাপ করতে বলে।
  5. Column নোডটি তার প্রথম Text চাইল্ডকে পরিমাপ করতে বলে।
  6. প্রথম Text নোডটি একটি লিফ নোড, তাই এটি একটি আকার রিপোর্ট করে এবং স্থাপনের নির্দেশাবলী ফেরত দেয়।
  7. Column নোডটি তার দ্বিতীয় Text চাইল্ডকে পরিমাপ করতে বলে।
  8. দ্বিতীয় Text নোডটি একটি লিফ নোড, তাই এটি একটি আকার রিপোর্ট করে এবং স্থাপনের নির্দেশাবলী ফেরত দেয়।
  9. এখন যেহেতু Column নোডটি তার চাইল্ড নোডগুলোকে পরিমাপ, আকার নির্ধারণ এবং স্থাপন করেছে, তাই এটি নিজের আকার ও অবস্থান নির্ধারণ করতে পারে।
  10. এখন যেহেতু রুট নোড Row তার চাইল্ড নোডগুলোকে পরিমাপ, আকার নির্ধারণ এবং স্থাপন করেছে, তাই এটি নিজের আকার ও অবস্থান নির্ধারণ করতে পারে।

সার্চ রেজাল্ট UI ট্রি-তে পরিমাপ, আকার এবং অবস্থানের ক্রম

কর্মক্ষমতা

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 ম্যাটেরিয়াল ডিজাইনের উপর ভিত্তি করে androidx.compose.material:material ডিপেন্ডেন্সির (যা Android Studio-তে একটি Compose প্রজেক্ট তৈরি করার সময় অন্তর্ভুক্ত থাকে) মাধ্যমে বিভিন্ন ধরণের কম্পোজেবল এলিমেন্ট সরবরাহ করে। Drawer , FloatingActionButton , এবং TopAppBar মতো এলিমেন্টগুলো সবই এতে রয়েছে।

ম্যাটেরিয়াল কম্পোনেন্টগুলো স্লট এপিআই (slot API) ব্যাপকভাবে ব্যবহার করে। এটি কম্পোজেবল কম্পোনেন্টের উপরে কাস্টমাইজেশনের একটি স্তর যোগ করার জন্য কম্পোজ (Compose) দ্বারা প্রবর্তিত একটি প্যাটার্ন। এই পদ্ধতি কম্পোনেন্টগুলোকে আরও নমনীয় করে তোলে, কারণ এগুলো একটি চাইল্ড এলিমেন্ট গ্রহণ করে যা নিজেকেই কনফিগার করতে পারে, ফলে চাইল্ডের প্রতিটি কনফিগারেশন প্যারামিটার প্রকাশ করার প্রয়োজন হয় না। স্লটগুলো ইউজার ইন্টারফেসে (UI) একটি খালি জায়গা রাখে, যা ডেভেলপার তার ইচ্ছামতো পূরণ করতে পারেন। উদাহরণস্বরূপ, একটি TopAppBar এ আপনি এই স্লটগুলো কাস্টমাইজ করতে পারেন:

একটি ম্যাটেরিয়াল কম্পোনেন্টস অ্যাপ বারে উপলব্ধ স্লটগুলি দেখানো একটি ডায়াগ্রাম।

কম্পোজেবলগুলো সাধারণত একটি content কম্পোজেবল ল্যাম্বডা গ্রহণ করে ( content: @Composable () -> Unit )। স্লট এপিআইগুলো নির্দিষ্ট ব্যবহারের জন্য একাধিক content প্যারামিটার প্রদান করে। উদাহরণস্বরূপ, TopAppBar আপনাকে title , navigationIcon , এবং actions জন্য কন্টেন্ট সরবরাহ করার সুযোগ দেয়।

উদাহরণস্বরূপ, Scaffold আপনাকে মৌলিক ম্যাটেরিয়াল ডিজাইন লেআউট কাঠামো ব্যবহার করে একটি UI বাস্তবায়ন করার সুযোগ দেয়। Scaffold সবচেয়ে প্রচলিত শীর্ষ-স্তরের ম্যাটেরিয়াল কম্পোনেন্ট, যেমন TopAppBar , BottomAppBar , FloatingActionButton এবং Drawer জন্য স্লট প্রদান করে। Scaffold ব্যবহার করে এই কম্পোনেন্টগুলোর সঠিক অবস্থান নিশ্চিত করা এবং তাদের একসাথে সঠিকভাবে কাজ করানো সহজ হয়।

JetNews নমুনা অ্যাপটি, যা একাধিক উপাদানকে অবস্থান দেওয়ার জন্য Scaffold ব্যবহার করে।

@Composable
fun HomeScreen(/*...*/) {
    ModalNavigationDrawer(drawerContent = { /* ... */ }) {
        Scaffold(
            topBar = { /*...*/ }
        ) { contentPadding ->
            // ...
        }
    }
}

{% হুবহু %} {% endverbatim %} {% হুবহু %} {% endverbatim %}