রচনায় ফ্লো লেআউট

FlowRow এবং FlowColumn হলো Row এবং Column মতো কম্পোজেবল, কিন্তু এদের মধ্যে পার্থক্য হলো, কন্টেইনারে জায়গা ফুরিয়ে গেলে আইটেমগুলো পরবর্তী লাইনে চলে যায়। এর ফলে একাধিক সারি বা কলাম তৈরি হয়। maxItemsInEachRow বা maxItemsInEachColumn সেট করার মাধ্যমে একটি লাইনে আইটেমের সংখ্যাও নিয়ন্ত্রণ করা যায়। প্রায়শই রেসপন্সিভ লেআউট তৈরি করতে FlowRow এবং FlowColumn ব্যবহার করা যায়— কোনো একটি ডাইমেনশনের জন্য আইটেমগুলো খুব বড় হলেও কন্টেন্ট কেটে যায় না, এবং maxItemsInEach* এর সাথে Modifier.weight(weight) এর সমন্বয়ে এমন লেআউট তৈরি করা যায় যা প্রয়োজনে একটি সারি বা কলামের প্রস্থ পূরণ বা প্রসারিত করতে পারে।

এর সাধারণ উদাহরণ হলো একটি চিপ বা ফিল্টারিং UI-এর ক্ষেত্রে:

একটি ফ্লোরোতে ৫টি চিপ, যেখানে আর কোনো জায়গা না থাকলে তা পরবর্তী লাইনে উপচে পড়ে।
চিত্র ১. FlowRow এর উদাহরণ

মৌলিক ব্যবহার

FlowRow বা FlowColumn ব্যবহার করতে, এই কম্পোজেবলগুলো তৈরি করুন এবং এর ভিতরে সেই আইটেমগুলো রাখুন যেগুলো স্ট্যান্ডার্ড ফ্লো অনুসরণ করবে:

@Composable
private fun FlowRowSimpleUsageExample() {
    FlowRow(modifier = Modifier.padding(8.dp)) {
        ChipItem("Price: High to Low")
        ChipItem("Avg rating: 4+")
        ChipItem("Free breakfast")
        ChipItem("Free cancellation")
        ChipItem("£50 pn")
    }
}

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

প্রবাহ বিন্যাসের বৈশিষ্ট্য

ফ্লো লেআউটের নিম্নলিখিত বৈশিষ্ট্য ও প্রপার্টিগুলো রয়েছে, যেগুলো ব্যবহার করে আপনি আপনার অ্যাপে বিভিন্ন লেআউট তৈরি করতে পারেন।

প্রধান অক্ষের বিন্যাস: অনুভূমিক বা উল্লম্ব বিন্যাস

প্রধান অক্ষ হলো সেই অক্ষ যার উপর আইটেমগুলো সাজানো থাকে (উদাহরণস্বরূপ, FlowRow তে আইটেমগুলো আনুভূমিকভাবে সাজানো হয়)। FlowRow এর horizontalArrangement প্যারামিটারটি আইটেমগুলোর মধ্যেকার ফাঁকা স্থান কীভাবে বণ্টিত হবে তা নিয়ন্ত্রণ করে।

নিচের সারণিতে FlowRow এর আইটেমগুলিতে horizontalArrangement সেট করার উদাহরণ দেখানো হলো:

FlowRow অনুভূমিক বিন্যাস সেট করা হয়েছে

ফলাফল

Arrangement.Start ( Default )

শুরু দিয়ে সাজানো আইটেম

Arrangement.SpaceBetween

মাঝখানে ফাঁকা জায়গা রেখে জিনিসপত্র সাজানো।

Arrangement.Center

কেন্দ্রে সাজানো জিনিসপত্র

Arrangement.End

শেষে সাজানো জিনিসপত্র

Arrangement.SpaceAround

চারপাশে জায়গা রেখে জিনিসপত্র সাজানো হয়েছে।

Arrangement.spacedBy(8.dp)

একটি নির্দিষ্ট dp দ্বারা ব্যবধানযুক্ত আইটেম

FlowColumn ক্ষেত্রেও verticalArrangement এর সাথে অনুরূপ বিকল্পগুলি উপলব্ধ, যার ডিফল্ট হলো Arrangement.Top

আড়াআড়ি অক্ষ বিন্যাস

ক্রস অ্যাক্সিস হলো প্রধান অ্যাক্সিসের বিপরীত দিকের অ্যাক্সিস। উদাহরণস্বরূপ, FlowRow তে এটি হলো ভার্টিকাল অ্যাক্সিস। কন্টেইনারের ভেতরের সামগ্রিক বিষয়বস্তু ক্রস অ্যাক্সিসে কীভাবে সাজানো থাকবে তা পরিবর্তন করতে, FlowRow জন্য verticalArrangement এবং FlowColumn জন্য horizontalArrangement ব্যবহার করুন।

FlowRow এর ক্ষেত্রে, আইটেমগুলিতে বিভিন্ন verticalArrangement সেট করার উদাহরণ নিচের টেবিলে দেখানো হলো:

FlowRow উল্লম্ব বিন্যাস সেট করা হয়েছে

ফলাফল

Arrangement.Top ( Default )

পাত্রের উপরের ব্যবস্থা

Arrangement.Bottom

পাত্রের নীচের ব্যবস্থা

Arrangement.Center

কন্টেইনার কেন্দ্র বিন্যাস

FlowColumn ক্ষেত্রেও horizontalArrangement সাথে অনুরূপ বিকল্পগুলি উপলব্ধ। ডিফল্ট ক্রস-অ্যাক্সিস অ্যারেঞ্জমেন্ট হলো Arrangement.Start

স্বতন্ত্র আইটেম সারিবদ্ধকরণ

আপনি হয়তো সারির মধ্যে থাকা প্রতিটি আইটেমকে ভিন্ন ভিন্ন অ্যালাইনমেন্টে সাজাতে চাইতে পারেন। এটি verticalArrangement এবং horizontalArrangement থেকে আলাদা, কারণ এটি আইটেমগুলোকে বর্তমান লাইনের মধ্যেই অ্যালাইন করে। আপনি Modifier.align() ব্যবহার করে এটি প্রয়োগ করতে পারেন।

উদাহরণস্বরূপ, যখন একটি FlowRow এর আইটেমগুলোর উচ্চতা ভিন্ন ভিন্ন হয়, তখন সারিটি সবচেয়ে বড় আইটেমটির উচ্চতা গ্রহণ করে এবং আইটেমগুলোতে Modifier.align(alignmentOption) প্রয়োগ করে:

FlowRow উল্লম্ব সারিবদ্ধকরণ সেট করা হয়েছে

ফলাফল

Alignment.Top ( Default )

শীর্ষে সারিবদ্ধ আইটেমগুলি

Alignment.Bottom

নিচের দিকে সারিবদ্ধ আইটেম

Alignment.CenterVertically

কেন্দ্রের দিকে সারিবদ্ধ আইটেমগুলি

FlowColumn জন্যও অনুরূপ বিকল্প উপলব্ধ আছে। ডিফল্ট অ্যালাইনমেন্ট হলো Alignment.Start

সারি বা কলামে সর্বাধিক আইটেম

maxItemsInEachRow বা maxItemsInEachColumn প্যারামিটারগুলো নির্ধারণ করে যে, পরবর্তী লাইনে যাওয়ার আগে প্রধান অক্ষে এক লাইনে সর্বাধিক কতগুলো আইটেম থাকতে পারবে। এর ডিফল্ট মান হলো Int.MAX_INT , যা লাইনের মধ্যে আঁটার মতো আকারের যতগুলো সম্ভব আইটেম রাখার অনুমতি দেয়।

উদাহরণস্বরূপ, maxItemsInEachRow সেট করলে প্রাথমিক লেআউটে মাত্র ৩টি আইটেম থাকতে বাধ্য হয়:

কোনো সর্বোচ্চ সীমা নির্ধারণ করা নেই

maxItemsInEachRow = 3

ফ্লো রো-তে কোনো সর্বোচ্চ সীমা নির্ধারণ করা নেই।ফ্লো রো-তে সর্বাধিক আইটেম সেট করা হয়েছে

আইটেমের ওজন

ওয়েট (Weight) একটি আইটেমের ফ্যাক্টর এবং যে লাইনে এটি রাখা হয়েছে, সেখানকার উপলব্ধ জায়গার উপর ভিত্তি করে আইটেমটির আকার বৃদ্ধি করে। গুরুত্বপূর্ণভাবে, একটি আইটেমের প্রস্থ গণনা করার জন্য ওয়েট যেভাবে ব্যবহৃত হয়, সেই ক্ষেত্রে FlowRow এবং Row এর মধ্যে পার্থক্য রয়েছে। Rows এর ক্ষেত্রে, ওয়েট সেই Row এর সমস্ত আইটেমের উপর ভিত্তি করে নির্ধারিত হয়। FlowRow এর ক্ষেত্রে, ওয়েট সেই লাইনের আইটেমগুলোর উপর ভিত্তি করে নির্ধারিত হয় যেখানে আইটেমটি রাখা হয়েছে , FlowRow কন্টেইনারের সমস্ত আইটেমের উপর নয়।

উদাহরণস্বরূপ, যদি আপনার কাছে ৪টি আইটেম থাকে যা একটি লাইনে পড়ে এবং প্রতিটির ওজন যথাক্রমে 1f, 2f, 1f3f হয়, তাহলে মোট ওজন হবে 7f । একটি সারি বা কলামের অবশিষ্ট স্থান 7f দ্বারা ভাগ করা হবে। তারপর, প্রতিটি আইটেমের প্রস্থ গণনা করা হবে: weight * (remainingSpace / totalWeight) ব্যবহার করে।

আপনি FlowRow বা FlowColumn সাথে Modifier.weight এবং max items-এর সমন্বয় ব্যবহার করে একটি গ্রিড-সদৃশ লেআউট তৈরি করতে পারেন। এই পদ্ধতিটি রেসপন্সিভ লেআউট তৈরির জন্য উপযোগী, যা আপনার ডিভাইসের আকারের সাথে নিজেকে মানিয়ে নেয়।

ওজন ব্যবহার করে কী কী করা যায় তার কয়েকটি ভিন্ন উদাহরণ রয়েছে। একটি উদাহরণ হলো একটি গ্রিড যেখানে আইটেমগুলো সমান আকারের, যেমনটি নিচে দেখানো হয়েছে:

ফ্লো রো দিয়ে তৈরি গ্রিড
চিত্র ২. FlowRow ব্যবহার করে গ্রিড তৈরি করা

সমান আকারের আইটেম দিয়ে একটি গ্রিড তৈরি করতে, আপনি নিম্নলিখিত পদ্ধতিগুলো অনুসরণ করতে পারেন:

val rows = 3
val columns = 3
FlowRow(
    modifier = Modifier.padding(4.dp),
    horizontalArrangement = Arrangement.spacedBy(4.dp),
    maxItemsInEachRow = rows
) {
    val itemModifier = Modifier
        .padding(4.dp)
        .height(80.dp)
        .weight(1f)
        .clip(RoundedCornerShape(8.dp))
        .background(MaterialColors.Blue200)
    repeat(rows * columns) {
        Spacer(modifier = itemModifier)
    }
}

গুরুত্বপূর্ণভাবে, যদি আপনি আরেকটি আইটেম যোগ করেন এবং এটিকে ৯ বারের পরিবর্তে ১০ বার পুনরাবৃত্তি করেন, তাহলে শেষ আইটেমটি পুরো শেষ কলামটি দখল করে নেবে, কারণ পুরো সারির মোট ওজন হলো 1f :

গ্রিডে শেষ আইটেমটি পূর্ণ আকারে থাকবে
চিত্র ৩। FlowRow ব্যবহার করে এমন একটি গ্রিড তৈরি করা যেখানে শেষ আইটেমটি সম্পূর্ণ প্রস্থ জুড়ে থাকে।

আপনি অন্যান্য Modifiers সাথে ওয়েট (weights) একত্রিত করতে পারেন, যেমন Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio) , অথবা Modifier.fillMaxWidth(fraction) । এই মডিফায়ারগুলো একটি FlowRow (বা FlowColumn )-এর ভেতরের আইটেমগুলোর রেসপন্সিভ সাইজিং নিশ্চিত করতে একসাথে কাজ করে।

আপনি বিভিন্ন আকারের আইটেম দিয়ে একটি পর্যায়ক্রমিক গ্রিডও তৈরি করতে পারেন, যেখানে দুটি আইটেম প্রতিটি অর্ধেক প্রস্থ জুড়ে থাকবে এবং একটি আইটেম পরবর্তী কলামের সম্পূর্ণ প্রস্থ জুড়ে থাকবে:

প্রবাহ সারি সহ বিকল্প গ্রিড
চিত্র ৪. পর্যায়ক্রমিক আকারের সারি সহ FlowRow

আপনি নিম্নলিখিত কোডটির সাহায্যে এটি করতে পারেন:

FlowRow(
    modifier = Modifier.padding(4.dp),
    horizontalArrangement = Arrangement.spacedBy(4.dp),
    maxItemsInEachRow = 2
) {
    val itemModifier = Modifier
        .padding(4.dp)
        .height(80.dp)
        .clip(RoundedCornerShape(8.dp))
        .background(Color.Blue)
    repeat(6) { item ->
        // if the item is the third item, don't use weight modifier, but rather fillMaxWidth
        if ((item + 1) % 3 == 0) {
            Spacer(modifier = itemModifier.fillMaxWidth())
        } else {
            Spacer(modifier = itemModifier.weight(0.5f))
        }
    }
}

ভগ্নাংশ আকার

Modifier.fillMaxWidth(fraction) ব্যবহার করে, আপনি কন্টেইনারের আকার নির্দিষ্ট করতে পারেন যা একটি আইটেম দখল করবে। এটি Row বা Column ক্ষেত্রে Modifier.fillMaxWidth(fraction) যেভাবে কাজ করে তার থেকে ভিন্ন, কারণ Row/Column আইটেমগুলো সম্পূর্ণ কন্টেইনারের প্রস্থের পরিবর্তে অবশিষ্ট প্রস্থের একটি শতাংশ দখল করে।

উদাহরণস্বরূপ, নিম্নলিখিত কোডটি FlowRow এবং Row ব্যবহার করার সময় ভিন্ন ফলাফল তৈরি করে:

FlowRow(
    modifier = Modifier.padding(4.dp),
    horizontalArrangement = Arrangement.spacedBy(4.dp),
    maxItemsInEachRow = 3
) {
    val itemModifier = Modifier
        .clip(RoundedCornerShape(8.dp))
    Box(
        modifier = itemModifier
            .height(200.dp)
            .width(60.dp)
            .background(Color.Red)
    )
    Box(
        modifier = itemModifier
            .height(200.dp)
            .fillMaxWidth(0.7f)
            .background(Color.Blue)
    )
    Box(
        modifier = itemModifier
            .height(200.dp)
            .weight(1f)
            .background(Color.Magenta)
    )
}

FlowRow : মাঝের আইটেম, যা সম্পূর্ণ কন্টেইনারের প্রস্থের ০.৭ ভগ্নাংশ জায়গা নেয়।

প্রবাহ সারি সহ ভগ্নাংশ প্রস্থ

Row : মাঝের আইটেমটি, যা Row অবশিষ্ট প্রস্থের ০.৭ শতাংশ জায়গা নেয়।

সারির সাথে ভগ্নাংশ প্রস্থ

fillMaxColumnWidth() এবং fillMaxRowHeight()

একটি FlowColumn বা FlowRow ভেতরের কোনো আইটেমে Modifier.fillMaxColumnWidth() অথবা Modifier.fillMaxRowHeight() প্রয়োগ করলে, একই কলাম বা সারির আইটেমগুলো ঐ কলাম/সারির সবচেয়ে বড় আইটেমটির সমান প্রস্থ বা উচ্চতা নেবে।

উদাহরণস্বরূপ, এই উদাহরণটিতে অ্যান্ড্রয়েড ডেজার্টের তালিকা প্রদর্শন করতে FlowColumn ব্যবহার করা হয়েছে। আপনি দেখতে পারেন যে, যখন আইটেমগুলিতে Modifier.fillMaxColumnWidth() প্রয়োগ করা হয় এবং যখন তা করা হয় না, তখন প্রতিটি আইটেমের প্রস্থে পার্থক্য দেখা যায় এবং আইটেমগুলি র‍্যাপ হয়ে যায়।

FlowColumn(
    Modifier
        .padding(20.dp)
        .fillMaxHeight()
        .fillMaxWidth(),
    horizontalArrangement = Arrangement.spacedBy(8.dp),
    verticalArrangement = Arrangement.spacedBy(8.dp),
    maxItemsInEachColumn = 5,
) {
    repeat(listDesserts.size) {
        Box(
            Modifier
                .fillMaxColumnWidth()
                .border(1.dp, Color.DarkGray, RoundedCornerShape(8.dp))
                .padding(8.dp)
        ) {

            Text(
                text = listDesserts[it],
                fontSize = 18.sp,
                modifier = Modifier.padding(3.dp)
            )
        }
    }
}

Modifier.fillMaxColumnWidth() প্রতিটি আইটেমে প্রয়োগ করা হয়েছে

fillMaxColumnWidth

কোনো প্রস্থ পরিবর্তন সেট করা নেই (আইটেম মোড়ানোর ক্ষেত্রে)

সর্বোচ্চ কলাম প্রস্থ সেট করা হয়নি।
{% হুবহু %} {% endverbatim %} {% হুবহু %} {% endverbatim %}