Adaptive Layout: asosiy tushunchalar, o'lcham sinflari va kvalifikatorlar

Muallif: IT Sectr Nashr etilgan: 2026-02-26 O'qish vaqti: 10 daq

Adaptive Layout — interfeyslarni yig'ishga yondashuv bo'lib, unda dastur turli qurilma turlari va ekran orientatsiyalari uchun turli maketlardan foydalanadi. Responsive design-dan farqli o'laroq, adaptive layout breakpoint nuqtalarida oldindan tayyorlangan layoutlar o'rtasida almashadi. Maqola iOS-da Size Classes va UITraitCollection, Android-da sw600dp/layout-w600dp kvalifikatorlarini va amaliy misollarni ko'rib chiqadi.

Asosiy fikrlar

  • Adaptive Layout — ekran o'lchami, orientatsiya va qurilma turiga qarab maketlarning diskret almashinuvi
  • Size Classes iOS-da fazoni gorizontal va vertikal bo'yicha Compact yoki Regular deb tasniflaydi
  • UITraitCollection — iOS muhit xususiyatlari konteyneri (o'lcham, masshtab, force touch, rang gamuti)
  • sw600dp — planshetlar uchun Android minimal en kvalifikatori (7" va undan katta)
  • layout-w600dp — joriy orientatsiyada yetarli joy bo'lganda ishga tushadigan mavjud en kvalifikatori

Adaptive Layout nima?

Adaptive Layout — interfeys qurish strategiyasi bo'lib, unda dasturchi har bir qurilma turi uchun alohida maketlar yaratadi va ekran xususiyatlariga qarab ular o'rtasida almashadi. Responsive design-dan farqli o'laroq, unda elementlar silliq oqadi, adaptive layout diskret almashinuvlardan foydalanadi: telefon — bitta layout, planshet — boshqa, desktop — uchinchi.

Apple Size Classes-ni iOS 8 da (2014) universal dasturlar (iPhone va iPad da ishlaydigan universal binaries) bilan birga taqdim etdi. Google smallestWidth (swdp) kvalifikatorini Android 3.2 da (2011) taqdim etdi. Ikkala mexanizm ham bir xil muammoni hal qiladi: dasturchiga kodni takrorlamasdan turli ekranlar uchun turli UI yaratish vositasini berish.

Zamonaviy Apple HIG va Google Material Design tavsiyalari bir nechta ekran o'lchamini qo'llab-quvvatlaydigan dasturlar uchun adaptive layout majburiy ekanligiga qo'shiladi. Google Play planshetlarga moslashishning yo'qligini kamchilik sifatida belgilaydi. App Store rasmiy talabga ega emas, lekin iPad foydalanuvchilari cho'zilgan iPhone dasturini emas, balki native tajribani kutishadi.

iOS Size Classes va UITraitCollection

Size Classes — iOS-ning har bir o'qda mavjud fazoni Compact yoki Regular deb belgilaydigan xususiyati. UITraitCollection — view iyerarxiyasi orqali muhit xususiyatlarini uzatish uchun iOS tizimi: o'lcham, ekran masshtabi, force touch capability, rang gamuti (light/dark), accessibility settings.

Qurilma / OrientatsiyaHorizontalVertical
iPhone portret (barcha modellar)CompactRegular
iPhone Plus/Pro Max landshaftRegularCompact
iPhone SE / mini landshaftCompactCompact
iPad portretRegularRegular
iPad landshaftRegularRegular
iPad Split View (1/3 ekran)CompactRegular

UITraitCollection tizim tomonidan yaratiladi va UIApplication dan UIWindow orqali har bir UIView ga uzatiladi. Orientatsiya yoki oyna o'lchami o'zgarganda (Split View) tizim yangi UITraitCollection yaratadi va traitCollectionDidChange ni chaqiradi. SwiftUI da o'zgarishlar Environment Values orqali kuzatiladi va view avtomatik qayta chiziladi.

Swift-da adaptiv layout namunasi

UIKit da UITraitCollection orqali moslashish trait collection o'zgarishlariga obuna bo'lish va layout-ni qayta qurish bilan amalga oshiriladi. Quyidagi misol iPhone uchun vertikal stack va iPad uchun split-maket o'rtasida almashadigan kontrollerni ko'rsatadi.

swift
// Size Classes bilan adaptiv kontroller
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: sidebar + content
        } else {
            showCompactLayout() // iPhone: tab bar + push
        }
    }

    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 metodi traits dagi har qanday o'zgarishda chaqiriladi, lekin biz faqat horizontalSizeClass ni tekshiramiz — maket o'zgarishi uchun eng muhim ko'rsatkich. iOS 17+ da o'zgarishlarga obuna bo'lmasdan reaktiv yangilash uchun UIViewController.horizontalSizeClass ni computed property sifatida ishlatish tavsiya etiladi.

Android kvalifikatorlari: sw600dp va w600dp

Android ikkita asosiy en kvalifikatorini taqdim etadi: swdp (smallestWidth) va wdp (available width). Farq muhim: sw — orientatsiyadan qat'i nazar minimal ekran eni, w — joriy orientatsiyani hisobga olgan holda mavjud en. sw belgilangan minimal en ga fizik jihatdan ega bo'lgan qurilma uchun layout yuklanishini kafolatlaydi. w aylanishga reaksiya beradi — landshaftda w600dp ishga tushishi mumkin, hatto portretda en 360 dp bo'lsa ham.

KvalifikatorShartQurilma namunasi
layout-sw600dpMinimal en ≥ 600 dpiPad (768 dp), Pixel C (900 dp)
layout-w600dpJoriy en ≥ 600 dpiPad Split View da (600 dp), landshaftda telefon
layout-landLandshaft orientatsiyasiGorizontal aylantirilgan har qanday qurilma
layout-sw720dpMinimal en ≥ 720 dpiPad Pro (833 dp), Galaxy Tab S9 (800 dp)

Android da resurs iyerarxiyasi: res/layout/activity_main.xml (telefon), res/layout-sw600dp/activity_main.xml (7" planshet), res/layout-w600dp-land/activity_main.xml (landshaftda telefon). Android joriy qurilma konfiguratsiyasiga mos keladigan eng spesifik kvalifikatorni tanlaydi. Mos fayl bo'lmasa, res/layout/ dan asosiy resurs ishlatiladi.

Kotlin-da adaptiv layout namunasi

Zamonaviy Android rivojlanishi resurslarni to'g'ridan-to'g'ri o'qish o'rniga oyna o'lchamini aniqlash uchun Jetpack WindowManager dan foydalanadi. Bu ekran o'lchami dinamik o'zgaradigan yig'iladigan qurilmalar uchun ayniqsa muhimdir (Galaxy Fold 6.2" dan 7.6" gacha ochiladi).

kotlin
// Jetpack WindowManager orqali moslashish
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("Telefon", 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 kutubxonasidan currentWindowAdaptiveInfo() komponenti interfeysni istalgan qurilmaga moslashtiradi: telefon, planshet, yig'iladigan, ChromeOS. En sinflari: COMPACT (0–600 dp), MEDIUM (600–840 dp), EXPANDED (>840 dp). Balandlik sinflari: COMPACT (0–480 dp), MEDIUM (480–900 dp), EXPANDED (>900 dp).

SwiftUI-da Adaptive Layout

SwiftUI Size Classes dan to'g'ridan-to'g'ri foydalanmasdan adaptiv layout uchun o'rnatilgan vositalarni taqdim etadi. AnyLayout, ViewThatFits va GeometryReader mavjud bo'shliqqa avtomatik moslashadigan interfeyslarni qurishga imkon beradi.

swift
// AnyLayout va ViewThatFits orqali SwiftUI moslashuvi
import SwiftUI

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

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

        layout {
            Label("Sevimlilar", systemImage: "star")
            Label("Oxirgi", systemImage: "clock")
            Label("Sozlamalar", systemImage: "gear")
        }
        .padding()
    }
}

// ViewThatFits — layout ni avtomatik tanlash
struct SmartLayout: View {
    var body: some View {
        ViewThatFits {
            HStack { // Prioritet 1: gorizontal
                CardView()
                CardView()
            }
            VStack { // Sig'masa — vertikal
                CardView()
                CardView()
            }
        }
    }
}

ViewThatFits — SwiftUI ning kuchli vositasi, kesilmasdan mavjud bo'shliqqa sig'adigan birinchi bola view-ni avtomatik tanlaydi. Bu oddiy adaptiv almashinuvlar uchun Size Classes ni aniq tekshirish zaruratini yo'q qiladi. AnyLayout view tanasida if-else holda layout turini (HStack/VStack) o'zgartirishga imkon beradi.

Jetpack Compose-da Adaptive Layout

Jetpack Compose adaptiv maket uchun WindowSizeClass (Material 3 adaptive kutubxonasidan) va BoxWithConstraints dan foydalanadi. XML kvalifikatorlaridan farqli o'laroq, Compose oyna o'lchamini runtime da aniqlaydi va konfiguratsiya o'zgarganda UI ni reaktiv qayta quradi.

kotlin
// BoxWithConstraints orqali Jetpack Compose moslashuvi
@Composable
fun AdaptiveList(items: List<String>) {
    BoxWithConstraints {
        val width = maxWidth

        if (width >= 600.dp) {
            // Planshet: ikki ustun (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 {
            // Telefon: navigatsiya bilan bir ustun
            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 tayyor komponentlarni taqdim etadi: ListDetailScaffold, SupportingPaneScaffold, NavigationSuiteScaffold. Bu komponentlar avtomatik ravishda WindowWidthSizeClass ga moslashadi — stacked (COMPACT) va side-by-side (MEDIUM/EXPANDED) o'rtasida almashadi. Dasturchi faqat namunani tanlashi va kontent panellarini uzatishi kerak.

Tez-tez beriladigan savollar

sw600dp va w600dp o'rtasidagi farq nima?

sw600dp (smallestWidth) — orientatsiyadan qat'i nazar minimal ekran eni. Har doim 7"+ planshetlarda ishlaydi. w600dp (available width) — joriy orientatsiyani hisobga olgan holda mavjud en. Eni 600 dp dan oshishi mumkin bo'lgan landshaftdagi telefonlarda ishlaydi.

iOS da UITraitCollection nima?

UITraitCollection — muhit xususiyatlarini o'z ichiga olgan iOS obyekti: size classes (horizontal/vertical), display scale, force touch capability, user interface idiom (iPhone/iPad), color gamut, accessibility settings. UIApplication dan view iyerarxiyasi orqali uzatiladi va orientatsiya yoki oyna o'lchami o'zgarganda yangilanadi.

Dasturni yig'iladigan qurilmalarga qanday moslashtirish kerak?

Jetpack WindowManager (Android) va UIScreen nativeBounds + traitCollection (iOS) dan foydalaning. Yig'iladigan qurilmalar ochilganda Size Class ni o'zgartiradi. Activity ni qayta ishga tushirmasdan oyna o'lchami o'zgarishlariga reaktiv obuna bilan kanonik layout (list-detail, supporting pane) asosidagi arxitektura tavsiya etiladi.

iPad uchun alohida storyboards yaratish kerakmi?

Yo'q. Size Classes variatsiyalari bo'lgan bitta storyboard yoki UIKit orqali programm layout dan foydalaning. SwiftUI umuman storyboards talab qilmaydi. iPad uchun alohida storyboards takrorlash yaratadi va texnik xizmat ko'rsatishni murakkablashtiradi — bitta maketni Size Classes orqali moslashtirish yaxshiroq.

Material 3 da canonical layouts nima?

Canonical layouts — Google dan tayyor adaptiv maket namunalari: list-detail (ro'yxat + tafsilot), supporting pane (kontent + harakat paneli), feed (kartalar). Har bir namuna uch holatni qo'llab-quvvatlaydi (compact/medium/expanded) va Material 3 Adaptive kutubxonasida ListDetailScaffold va SupportingPaneScaffold orqali amalga oshirilgan.

Xulosa

  • Adaptive Layout — turli qurilmalar uchun breakpoint nuqtalarida maketlarning diskret almashinuvi
  • Size Classes iOS (Compact/Regular) iPhone, iPad va Split View uchun layout ni belgilaydi
  • UITraitCollection — muhit xususiyatlarini view iyerarxiyasi orqali uzatish mexanizmi
  • sw600dp — 7"+ planshetlar uchun Android minimal en kvalifikatori
  • w600dp — landshaftga aylantirilganda ishga tushadigan mavjud en kvalifikatori
  • Jetpack WindowManager WindowSizeClass ni taqdim etadi (WindowWidthSizeClass: COMPACT/MEDIUM/EXPANDED)
  • Material 3 Adaptive — avtomatik moslashuv bilan tayyor komponentlar (ListDetailScaffold)

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing