Compose-এ Flow লেআউট

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

চিপ বা ফিল্টারিং UI-এর জন্য সাধারণ উদাহরণ:

FlowRow-তে ৫টি চিপ, আরও জায়গা উপলভ্য না থাকলে পরবর্তী লাইনে ওভারফ্লো দেখানো হচ্ছে।
ছবি ১. 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

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

আইটেমের ওজন

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

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

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

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

ফ্লো রো সহ গ্রিড তৈরি করা হয়েছে
ছবি ২. 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-এর সাথে ওজন একত্রিত করতে পারেন, যেমন 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) ব্যবহার করে, আপনি কন্টেনারের সাইজ নির্দিষ্ট করতে পারবেন যেটি কোনও আইটেমকে নিতে হবে। Modifier.fillMaxWidth(fraction)-এর ক্ষেত্রে এটি আলাদাভাবে কাজ করে যখন Row বা Column-এ প্রয়োগ করা হয়, যেখানে 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() প্রয়োগ করলে, একই কলাম বা সারিতে থাকা আইটেমগুলি কলাম/সারির সবচেয়ে বড় আইটেমের মতো একই প্রস্থ বা উচ্চতা নেয়।

যেমন, এই উদাহরণে Android ডেজার্টের তালিকা দেখানোর জন্য 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

প্রস্থে কোনও পরিবর্তন সেট করা হয়নি (আইটেম র‍্যাপ করা হচ্ছে)

কলামের সর্বাধিক প্রস্থ সেট করা নেই