Adaptive Layout: মূল ধারণা, সাইজ ক্লাস এবং কোয়ালিফায়ার

লেখক: IT Sectr প্রকাশিত: 2026-02-26 পড়ার সময়: 10 মিনিট

Adaptive Layout হল ইন্টারফেস লেআউটের একটি পদ্ধতি যেখানে অ্যাপ্লিকেশন বিভিন্ন ধরনের ডিভাইস এবং স্ক্রিন ওরিয়েন্টেশনের জন্য ভিন্ন ভিন্ন লেআউট ব্যবহার করে। responsive design-এর বিপরীতে, adaptive layout ব্রেকপয়েন্টে পূর্ব-নির্মিত লেআউটের মধ্যে সুইচ করে। এই নিবন্ধটি iOS-এ Size Classes এবং UITraitCollection, Android-এ sw600dp/layout-w600dp কোয়ালিফায়ার এবং ব্যবহারিক উদাহরণগুলি বিশ্লেষণ করে।

মূল পয়েন্ট

  • Adaptive Layout — স্ক্রিন সাইজ, ওরিয়েন্টেশন এবং ডিভাইস的类型 অনুযায়ী লেআউটের বিচ্ছিন্ন সুইচিং
  • Size Classes iOS-এ স্থানকে অনুভূমিক এবং উল্লম্বভাবে Compact বা Regular হিসাবে শ্রেণীবদ্ধ করে
  • UITraitCollection — iOS পরিবেশ বৈশিষ্ট্যের ধারক (আকার, স্কেল, force touch, কালার গামুট)
  • sw600dp — ট্যাবলেট (7\" এবং বড়) এর জন্য Android ন্যূনতম প্রস্থ কোয়ালিফায়ার
  • layout-w600dp — উপলব্ধ প্রস্থ কোয়ালিফায়ার যা বর্তমান ওরিয়েন্টেশনে পর্যাপ্ত স্থান থাকলে সক্রিয় হয়

Adaptive Layout কী?

Adaptive Layout হল একটি UI কৌশল যেখানে ডেভেলপার প্রতিটি ডিভাইস ধরনের জন্য পৃথক লেআউট তৈরি করে এবং স্ক্রিন বৈশিষ্ট্যের ভিত্তিতে তাদের মধ্যে সুইচ করে। responsive design-এর বিপরীতে যেখানে উপাদানগুলি মসৃণভাবে প্রবাহিত হয়, adaptive layout বিচ্ছিন্ন সুইচিং ব্যবহার করে: ফোন — একটি লেআউট, ট্যাবলেট — আরেকটি, ডেস্কটপ — তৃতীয়টি।

Apple iOS 8 (2014)-এ ইউনিভার্সাল অ্যাপ্লিকেশন (iPhone এবং iPad উভয়েই চলমান বাইনারি) সহ Size Classes চালু করে। Google Android 3.2 (2011)-এ smallestWidth কোয়ালিফায়ার (swdp) উপস্থাপন করে। উভয় প্রক্রিয়া একই সমস্যার সমাধান করে: ডেভেলপারকে বিভিন্ন স্ক্রিনের জন্য ভিন্ন UI তৈরি করার সরঞ্জাম দেওয়া কোড পুনরাবৃত্তি ছাড়াই।

আধুনিক Apple HIG এবং Google Material Design নির্দেশিকা একমত যে একাধিক স্ক্রিন সাইজ সমর্থন করে এমন অ্যাপ্লিকেশনের জন্য adaptive layout অপরিহার্য। Google Play ট্যাবলেট অভিযোজনের অভাবকে ত্রুটি হিসাবে চিহ্নিত করে। App Store-এর কোনো আনুষ্ঠানিক প্রয়োজনীয়তা নেই, তবে iPad ব্যবহারকারীরা প্রসারিত iPhone অ্যাপের পরিবর্তে নেটিভ অভিজ্ঞতা আশা করেন।

iOS-এ Size Classes এবং UITraitCollection

Size Classes হল iOS-এর একটি বৈশিষ্ট্য যা প্রতিটি অক্ষে উপলব্ধ স্থানকে Compact (সংকুচিত) বা Regular (নিয়মিত) হিসাবে সংজ্ঞায়িত করে। UITraitCollection হল একটি iOS সিস্টেম যা ভিউ হায়ারার্কির মাধ্যমে পরিবেশ বৈশিষ্ট্য প্রেরণ করে: আকার, স্ক্রিন স্কেল, force touch ক্ষমতা, কালার গামুট (হালকা/গাঢ়), অ্যাক্সেসিবিলিটি সেটিংস।

ডিভাইস / ওরিয়েন্টেশনঅনুভূমিকউল্লম্ব
iPhone পোর্ট্রেট (সব মডেল)CompactRegular
iPhone Plus/Pro Max ল্যান্ডস্কেপRegularCompact
iPhone SE / mini ল্যান্ডস্কেপCompactCompact
iPad পোর্ট্রেটRegularRegular
iPad ল্যান্ডস্কেপRegularRegular
iPad Split View (1/3 স্ক্রিন)CompactRegular

UITraitCollection সিস্টেম দ্বারা গঠিত হয় এবং UIApplication থেকে UIWindow এর মাধ্যমে প্রতিটি UIView-এ প্রেরিত হয়। ওরিয়েন্টেশন বা উইন্ডো সাইজ (Split View) পরিবর্তন হলে সিস্টেম একটি নতুন UITraitCollection তৈরি করে এবং traitCollectionDidChange কল করে। SwiftUI-তে, পরিবর্তনগুলি Environment Values-এর মাধ্যমে ট্র্যাক করা হয় এবং ভিউ স্বয়ংক্রিয়ভাবে পুনরায় আঁকা হয়।

Swift-এ অ্যাডাপ্টিভ লেআউটের উদাহরণ

UIKit-এ UITraitCollection-এর মাধ্যমে অভিযোজন trait collection পরিবর্তনে সাবস্ক্রাইব করে এবং লেআউট পুনর্নির্মাণ করে বাস্তবায়িত হয়। নীচের উদাহরণটি একটি কন্ট্রোলার দেখায় যা iPhone-এর জন্য উল্লম্ব স্ট্যাক এবং iPad-এর জন্য স্প্লিট লেআউটের মধ্যে সুইচ করে।

swift
// Size Classes সহ অ্যাডাপ্টিভ কন্ট্রোলার
import UIKit

final class AdaptiveViewController: UIViewController {

    private let compactStack = UIStackView()
    private let regularStack = UIStackView()
    private let sidebar = UIView()
    private let content = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
        updateLayout(for: traitCollection)
    }

    override func traitCollectionDidChange(
        _ previousTraitCollection: UITraitCollection?
    ) {
        super.traitCollectionDidChange(previousTraitCollection)
        if traitCollection.horizontalSizeClass
            != previousTraitCollection?.horizontalSizeClass {
            updateLayout(for: traitCollection)
        }
    }

    private func updateLayout(for traits: UITraitCollection) {
        if traits.horizontalSizeClass == .regular {
            showRegularLayout() // iPad: সাইডবার + বিষয়বস্তু
        } else {
            showCompactLayout() // iPhone: ট্যাব বার + পুশ
        }
    }

    private func showRegularLayout() {
        view.subviews.forEach { $0.removeFromSuperview() }
        regularStack.addArrangedSubview(sidebar)
        regularStack.addArrangedSubview(content)
        regularStack.frame = view.bounds
        regularStack.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(regularStack)
    }

    private func showCompactLayout() {
        view.subviews.forEach { $0.removeFromSuperview() }
        compactStack.addArrangedSubview(content)
        compactStack.frame = view.bounds
        compactStack.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(compactStack)
    }

    private func setupViews() {
        sidebar.backgroundColor = .systemGray6
        content.backgroundColor = .systemBackground
        compactStack.axis = .vertical
        regularStack.axis = .horizontal
    }
}

traitCollectionDidChange মেথড যেকোনো ট্রেইট পরিবর্তনে কল করা হয়, কিন্তু আমরা শুধু horizontalSizeClass পরীক্ষা করি — লেআউট পরিবর্তনের জন্য সবচেয়ে গুরুত্বপূর্ণ নির্দেশক। iOS 17+-এ পরিবর্তনে সাবস্ক্রাইব না করে প্রতিক্রিয়াশীল আপডেটের জন্য UIViewController.horizontalSizeClass কে গণিত সম্পত্তি হিসাবে ব্যবহার করার পরামর্শ দেওয়া হয়।

Android কোয়ালিফায়ার: sw600dp এবং w600dp

Android দুটি প্রধান প্রস্থ কোয়ালিফায়ার প্রদান করে: swdp (smallestWidth) এবং wdp (available width)। পার্থক্য গুরুত্বপূর্ণ: sw হল ওরিয়েন্টেশন নির্বিশেষে ন্যূনতম স্ক্রিন প্রস্থ, w হল বর্তমান ওরিয়েন্টেশন বিবেচনা করে উপলব্ধ প্রস্থ। sw নিশ্চিত করে যে লেআউটটি সেই ডিভাইসের জন্য লোড হবে যার শারীরিকভাবে নির্দিষ্ট ন্যূনতম প্রস্থ রয়েছে। w রোটেশনে সাড়া দেয় — ল্যান্ডস্কেপে, w600dp সক্রিয় হতে পারে এমনকি পোর্ট্রেটে প্রস্থ 360 dp হলেও।

কোয়ালিফায়ারশর্তডিভাইস উদাহরণ
layout-sw600dpন্যূনতম প্রস্থ ≥ 600 dpiPad (768 dp), Pixel C (900 dp)
layout-w600dpবর্তমান প্রস্থ ≥ 600 dpSplit View-এ iPad (600 dp), ল্যান্ডস্কেপে ফোন
layout-landল্যান্ডস্কেপ ওরিয়েন্টেশনযেকোনো ডিভাইস অনুভূমিকভাবে ঘোরানো
layout-sw720dpন্যূনতম প্রস্থ ≥ 720 dpiPad Pro (833 dp), Galaxy Tab S9 (800 dp)

Android-এ রিসোর্স হায়ারার্কি: res/layout/activity_main.xml (ফোন), res/layout-sw600dp/activity_main.xml (7\" ট্যাবলেট), res/layout-w600dp-land/activity_main.xml (ল্যান্ডস্কেপে ফোন)। Android বর্তমান ডিভাইস কনফিগারেশনের সাথে মেলে এমন সবচেয়ে নির্দিষ্ট কোয়ালিফায়ার নির্বাচন করে। যখন কোনো ম্যাচিং ফাইল থাকে না, তখন res/layout/ থেকে বেস রিসোর্স ব্যবহার করা হয়।

Kotlin-এ অ্যাডাপ্টিভ লেআউটের উদাহরণ

আধুনিক Android ডেভেলপমেন্ট সরাসরি রিসোর্স পড়ার পরিবর্তে উইন্ডো সাইজ নির্ধারণ করতে Jetpack WindowManager ব্যবহার করে। এটি বিশেষ করে ফোল্ডেবল ডিভাইসের জন্য গুরুত্বপূর্ণ যেখানে স্ক্রিন সাইজ গতিশীলভাবে পরিবর্তিত হয় (Galaxy Fold 6.2\" থেকে 7.6\" পর্যন্ত খোলে)।

kotlin
// Jetpack WindowManager-এর মাধ্যমে অভিযোজন
import androidx.window.core.layout.WindowHeightSizeClass
import androidx.window.core.layout.WindowSizeClass
import androidx.window.core.layout.WindowWidthSizeClass

@OptIn(ExperimentalLayoutApi::class)
@Composable
fun AdaptiveScreen() {
    val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass

    FlowRow(
        verticalAlignment = Arrangement.Top,
        horizontalArrangement = when (windowSizeClass.windowWidthSizeClass) {
            WindowWidthSizeClass.EXPANDED -> Arrangement.SpaceEvenly
            else -> Arrangement.Start
        }
    ) {
        when (windowSizeClass.windowWidthSizeClass) {
            WindowWidthSizeClass.COMPACT -> {
                CompactContent()
            }
            WindowWidthSizeClass.MEDIUM -> {
                MediumContent()
            }
            WindowWidthSizeClass.EXPANDED -> {
                ExpandedContent()
            }
        }
    }
}

@Composable
private fun CompactContent() {
    Column(modifier = Modifier.padding(16.dp)) {
        Text("ফোন", style = MaterialTheme.typography.headlineSmall)
        ListContent()
    }
}

@Composable
private fun MediumContent() {
    Row(modifier = Modifier.padding(24.dp)) {
        NavigationRail { ... }
        Column { ListContent() }
    }
}

@Composable
private fun ExpandedContent() {
    Row(modifier = Modifier.padding(32.dp)) {
        PermanentNavigationDrawer { ... }
        Column {
            ListContent()
        }
        DetailPane()
    }
}

androidx.window লাইব্রেরির currentWindowAdaptiveInfo() কম্পোনেন্ট যেকোনো ডিভাইসের জন্য ইন্টারফেস অভিযোজিত করে: ফোন, ট্যাবলেট, ফোল্ডেবল, ChromeOS। প্রস্থ ক্লাস: COMPACT (0–600 dp), MEDIUM (600–840 dp), EXPANDED (>840 dp)। উচ্চতা ক্লাস: COMPACT (0–480 dp), MEDIUM (480–900 dp), EXPANDED (>900 dp)।

SwiftUI-তে Adaptive Layout

SwiftUI Size Classes সরাসরি ব্যবহার না করেই অ্যাডাপ্টিভ লেআউটের জন্য বিল্ট-ইন টুল সরবরাহ করে। AnyLayout, ViewThatFits এবং GeometryReader এমন ইন্টারফেস তৈরি করতে দেয় যা স্বয়ংক্রিয়ভাবে উপলব্ধ স্থানের সাথে খাপ খায়।

swift
// AnyLayout এবং ViewThatFits-এর মাধ্যমে SwiftUI অভিযোজন
import SwiftUI

struct AdaptiveGrid: View {
    @Environment(\.horizontalSizeClass) private var hSizeClass

    var body: some View {
        let layout = hSizeClass == .regular
            ? AnyLayout(HStackLayout())
            : AnyLayout(VStackLayout())

        layout {
            Label("পছন্দসই", systemImage: "star")
            Label("সাম্প্রতিক", systemImage: "clock")
            Label("সেটিংস", systemImage: "gear")
        }
        .padding()
    }
}

// ViewThatFits — স্বয়ংক্রিয় লেআউট নির্বাচন
struct SmartLayout: View {
    var body: some View {
        ViewThatFits {
            HStack { // অগ্রাধিকার 1: অনুভূমিক
                CardView()
                CardView()
            }
            VStack { // যদি না ফিট হয় — উল্লম্ব
                CardView()
                CardView()
            }
        }
    }
}

ViewThatFits একটি শক্তিশালী SwiftUI টুল যা স্বয়ংক্রিয়ভাবে প্রথম চাইল্ড ভিউ নির্বাচন করে যা ক্লিপিং ছাড়াই উপলব্ধ স্থানে ফিট করে। এটি সাধারণ অ্যাডাপ্টিভ সুইচিংয়ের জন্য Size Classes স্পষ্টভাবে পরীক্ষা করার প্রয়োজনীয়তা দূর করে। AnyLayout ভিউ বডিতে if-else ছাড়াই লেআউট টাইপ (HStack/VStack) পরিবর্তন করতে দেয়।

Jetpack Compose-এ Adaptive Layout

Jetpack Compose অ্যাডাপ্টিভ লেআউটের জন্য WindowSizeClass (Material 3 adaptive লাইব্রেরি থেকে) এবং BoxWithConstraints ব্যবহার করে। XML কোয়ালিফায়ারের বিপরীতে, Compose রানটাইমে উইন্ডো সাইজ নির্ধারণ করে এবং কনফিগারেশন পরিবর্তনে প্রতিক্রিয়াশীলভাবে UI পুনর্গঠন করে।

kotlin
// BoxWithConstraints-এর মাধ্যমে Jetpack Compose অ্যাডাপ্টিভ
@Composable
fun AdaptiveList(items: List<String>) {
    BoxWithConstraints {
        val width = maxWidth

        if (width >= 600.dp) {
            // ট্যাবলেট: দুই কলাম (list-detail)
            Row(modifier = Modifier.fillMaxSize()) {
                LazyColumn(modifier = Modifier.weight(1f)) {
                    items(items) { item ->
                        ListItem(text = item)
                    }
                }
                var selected by remember { mutableStateOf(items.first()) }
                DetailPanel(item = selected)
                    .weight(2f)
            }
        } else {
            // ফোন: নেভিগেশন সহ এক কলাম
            LazyColumn(modifier = Modifier.fillMaxSize()) {
                items(items) { item ->
                    ListItem(text = item, onClick = { navigateToDetail(item) })
                }
            }
        }
    }
}

@Composable
fun AdaptiveListMaterial3() {
    val windowClass = currentWindowAdaptiveInfo().windowSizeClass

    AdaptiveLayout(
        layout = windowClass.windowWidthSizeClass
    ) {
        when (windowClass.windowWidthSizeClass) {
            WindowWidthSizeClass.COMPACT -> {
                ListDetailScaffold(
                    isDetailOnly = false,
                    list = { ListPane() },
                    detail = { DetailPane() }
                )
            }
            else -> {
                ListDetailScaffold(
                    isDetailOnly = false,
                    list = { ListPane() },
                    detail = { DetailPane() }
                )
            }
        }
    }
}

Material 3 Adaptive Layouts প্রস্তুত কম্পোনেন্ট সরবরাহ করে: ListDetailScaffold, SupportingPaneScaffold, NavigationSuiteScaffold। এই কম্পোনেন্টগুলি স্বয়ংক্রিয়ভাবে WindowWidthSizeClass-এর সাথে খাপ খায় — স্ট্যাকড (COMPACT) এবং সাইড-বাই-সাইড (MEDIUM/EXPANDED) এর মধ্যে সুইচ করে। ডেভেলপারকে শুধু একটি প্যাটার্ন বেছে নিতে এবং কন্টেন্ট প্যানেল পাস করতে হবে।

সচরাচর জিজ্ঞাসিত প্রশ্ন

sw600dp এবং w600dp-এর মধ্যে পার্থক্য কী?

sw600dp (smallestWidth) — ওরিয়েন্টেশন নির্বিশেষে ন্যূনতম স্ক্রিন প্রস্থ। সবসময় 7\"+ ট্যাবলেটে সক্রিয় হয়। w600dp (available width) — বর্তমান ওরিয়েন্টেশন বিবেচনা করে উপলব্ধ প্রস্থ। ল্যান্ডস্কেপে ফোনে সক্রিয় হয় যেখানে প্রস্থ 600 dp-এর বেশি হতে পারে।

iOS-এ UITraitCollection কী?

UITraitCollection একটি iOS অবজেক্ট যা পরিবেশ বৈশিষ্ট্য ধারণ করে: size classes (অনুভূমিক/উল্লম্ব), ডিসপ্লে স্কেল, force touch ক্ষমতা, ইউজার ইন্টারফেস idiom (iPhone/iPad), কালার গামুট, অ্যাক্সেসিবিলিটি সেটিংস। এটি UIApplication থেকে ভিউ হায়ারার্কির মাধ্যমে প্রেরিত হয় এবং ওরিয়েন্টেশন বা উইন্ডো সাইজ পরিবর্তনে পরিবর্তিত হয়।

কীভাবে ফোল্ডেবল ডিভাইসের জন্য অ্যাপ অভিযোজিত করবেন?

Jetpack WindowManager (Android) এবং UIScreen nativeBounds + traitCollection (iOS) ব্যবহার করুন। ফোল্ডেবল ডিভাইসগুলি খোলার সময় Size Class পরিবর্তন করে। ক্যানোনিকাল লেআউট (list-detail, supporting pane) ভিত্তিক আর্কিটেকচার সুপারিশ করা হয় যেখানে Activity পুনরায় চালু না করেই উইন্ডো সাইজ পরিবর্তনের প্রতিক্রিয়াশীল সাবস্ক্রিপশন থাকে।

iPad-এর জন্য আলাদা storyboards তৈরি করা প্রয়োজন কি?

না। Size Class ভ্যারিয়েশন সহ একটি একক storyboard বা UIKit-এর মাধ্যমে প্রোগ্রামেটিক লেআউট ব্যবহার করুন। SwiftUI-তে storyboards-এর মোটেই প্রয়োজন নেই। iPad-এর জন্য আলাদা storyboards পুনরাবৃত্তি তৈরি করে এবং রক্ষণাবেক্ষণ জটিল করে তোলে — Size Classes-এর মাধ্যমে একটি লেআউট অভিযোজিত করা ভাল।

Material 3-এ ক্যানোনিকাল লেআউট কী?

Canonical layouts হল Google-এর তৈরি অ্যাডাপ্টিভ লেআউট প্যাটার্ন: list-detail (তালিকা + বিস্তারিত), supporting pane (সামগ্রী + অ্যাকশন প্যানেল), feed (কার্ড)। প্রতিটি প্যাটার্ন তিনটি অবস্থা (compact/medium/expanded) সমর্থন করে এবং Material 3 Adaptive লাইব্রেরিতে ListDetailScaffold এবং SupportingPaneScaffold-এর মাধ্যমে বাস্তবায়িত।

সারাংশ

  • Adaptive Layout — বিভিন্ন ডিভাইসের জন্য ব্রেকপয়েন্টে বিচ্ছিন্ন লেআউট সুইচিং
  • Size Classes iOS (Compact/Regular) iPhone, iPad এবং Split View-এর জন্য লেআউট সংজ্ঞায়িত করে
  • UITraitCollection — ভিউ হায়ারার্কির মাধ্যমে পরিবেশ বৈশিষ্ট্য প্রেরণের প্রক্রিয়া
  • sw600dp — 7\"+ ট্যাবলেটের জন্য Android ন্যূনতম প্রস্থ কোয়ালিফায়ার
  • w600dp — উপলব্ধ প্রস্থ কোয়ালিফায়ার যা ল্যান্ডস্কেপে ঘোরালে সক্রিয় হয়
  • Jetpack WindowManager WindowSizeClass সরবরাহ করে (WindowWidthSizeClass: COMPACT/MEDIUM/EXPANDED)
  • Material 3 Adaptive — স্বয়ংক্রিয় অভিযোজন সহ প্রস্তুত কম্পোনেন্ট (ListDetailScaffold)

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন