Adaptive Layout: əsas anlayışlar, ölçü sinifləri və kvalifikatorlar

Müəllif: IT Sectr Dərc olunub: 2026-02-26 Oxuma vaxtı: 10 dəq

Adaptive Layout — interfeyslərin yığılmasına yanaşma, burada tətbiq müxtəlif cihaz növləri və ekran oriyentasiyaları üçün fərqli maketlər istifadə edir. Responsive design-dən fərqli olaraq, adaptive layout breakpoint nöqtələrində əvvəlcədən hazırlanmış layoutlar arasında keçid edir. Məqalə iOS-da Size Classes və UITraitCollection, Android-də sw600dp/layout-w600dp kvalifikatorlarını və praktiki nümunələri izah edir.

Əsas məqamlar

  • Adaptive Layout — ekran ölçüsü, oriyentasiya və cihaz növündən asılı olaraq maketlərin diskret dəyişdirilməsi
  • Size Classes iOS-da məkanı üfüqi və şaquli olaraq Compact və ya Regular kimi təsnif edir
  • UITraitCollection — iOS mühit xüsusiyyətləri konteyneri (ölçü, miqyas, force touch, rəng gamutu)
  • sw600dp — planşetlər üçün Android minimum en kvalifikatoru (7" və daha çox)
  • layout-w600dp — cari oriyentasiyada kifayət qədər yer olduqda işə düşən əlçatan en kvalifikatoru

Adaptive Layout nədir?

Adaptive Layout — interfeys qurma strategiyası, burada proqramçı hər cihaz növü üçün ayrı maketlər yaradır və ekran xüsusiyyətlərinə əsasən onlar arasında keçid edir. Responsive design-dən fərqli olaraq, burada elementlər axıcı şəkildə yerləşmir, əksinə diskret keçidlər istifadə olunur: telefon — bir layout, planşet — başqa, desktop — üçüncü.

Apple Size Classes-ı iOS 8-də (2014) universal tətbiqlərlə (həm iPhone, həm də iPad-də işləyən universal binaries) təqdim etdi. Google smallestWidth (swdp) kvalifikatorunu Android 3.2-də (2011) təqdim etdi. Hər iki mexanizm eyni problemi həll edir: proqramçıya kod təkrarlamadan müxtəlif ekranlar üçün fərqli UI yaratmaq aləti vermək.

Müasir Apple HIG və Google Material Design tövsiyələri bir neçə ekran ölçüsünü dəstəkləyən tətbiqlər üçün adaptive layout-un məcburi olduğunu bildirir. Google Play planşetlərə uyğunlaşmanın olmamasını çatışmazlıq kimi qeyd edir. App Store-un rəsmi tələbi yoxdur, lakin iPad istifadəçiləri uzadılmış iPhone tətbiqi deyil, native təcrübə gözləyirlər.

iOS Size Classes və UITraitCollection

Size Classes — iOS-un hər oxda mövcud məkanı kompakt (Compact) və ya regular (Regular) kimi təyin edən xüsusiyyəti. UITraitCollection — mühit xüsusiyyətlərini view iyerarxiyası ilə ötürmək üçün iOS sistemi: ölçü, ekran miqyası, force touch capability, rəng gamutu (light/dark), accessibility settings.

Cihaz / OriyentasiyaHorizontalVertical
iPhone portret (bütün modellər)CompactRegular
iPhone Plus/Pro Max landşaftRegularCompact
iPhone SE / mini landşaftCompactCompact
iPad portretRegularRegular
iPad landşaftRegularRegular
iPad Split View (1/3 ekran)CompactRegular

UITraitCollection sistem tərəfindən yaradılır və UIApplication-dən UIWindow vasitəsilə hər UIView-ə ötürülür. Oriyentasiya və ya pəncərə ölçüsü dəyişdikdə (Split View) sistem yeni UITraitCollection yaradır və traitCollectionDidChange-i çağırır. SwiftUI-də dəyişikliklər Environment Values vasitəsilə izlənilir və view avtomatik yenidən çəkilir.

Swift-də adaptiv layout nümunəsi

UIKit-də UITraitCollection vasitəsilə adaptasiya trait collection dəyişikliklərinə abunə olmaq və layout-u yenidən qurmaqla həyata keçirilir. Aşağıdakı nümunə iPhone üçün şaquli stack və iPad üçün split-maket arasında keçid edən kontrolleri göstərir.

swift
// Size Classes ilə 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 metodu traits-də hər hansı dəyişiklik olduqda çağırılır, lakin biz yalnız horizontalSizeClass-ı yoxlayırıq — maket dəyişikliyi üçün ən əhəmiyyətli göstərici. iOS 17+-da dəyişikliklərə abunə olmadan reaktiv yeniləmə üçün UIViewController.horizontalSizeClass-dan computed property kimi istifadə etmək tövsiyə olunur.

Android kvalifikatorları: sw600dp və w600dp

Android iki əsas en kvalifikatoru təqdim edir: swdp (smallestWidth) və wdp (available width). Fərq kritikdir: sw — oriyentasiyadan asılı olmayaraq minimum ekran eni, w — cari oriyentasiyanı nəzərə alan əlçatan en. sw göstərilən minimum enə fiziki olaraq sahib olan cihaz üçün layout-un yüklənəcəyinə zəmanət verir. w fırlanmaya reaksiya verir — landşaftda w600dp işə düşə bilər, hətta portretdə en 360 dp olsa belə.

KvalifikatorŞərtCihaz nümunəsi
layout-sw600dpMinimum en ≥ 600 dpiPad (768 dp), Pixel C (900 dp)
layout-w600dpCari en ≥ 600 dpiPad Split View-də (600 dp), landşaftda telefon
layout-landLandşaft oriyentasiyasıÜfüqi vəziyyətdə olan istənilən cihaz
layout-sw720dpMinimum en ≥ 720 dpiPad Pro (833 dp), Galaxy Tab S9 (800 dp)

Android-də resurs iyerarxiyası: res/layout/activity_main.xml (telefon), res/layout-sw600dp/activity_main.xml (7" planşet), res/layout-w600dp-land/activity_main.xml (landşaftda telefon). Android cari cihaz konfiqurasiyasına uyğun ən spesifik kvalifikatoru seçir. Uyğun fayl olmadıqda, res/layout/-dan əsas resurs istifadə olunur.

Kotlin-də adaptiv layout nümunəsi

Müasir Android inkişafı resursların birbaşa oxunması əvəzinə pəncərə ölçüsünü təyin etmək üçün Jetpack WindowManager istifadə edir. Bu, ekran ölçüsünün dinamik dəyişdiyi qatlanan cihazlar üçün xüsusilə vacibdir (Galaxy Fold 6,2"-dən 7,6"-yə açılır).

kotlin
// Jetpack WindowManager vasitəsilə adaptasiya
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 kitabxanasından currentWindowAdaptiveInfo() komponenti interfeysi istənilən cihaza uyğunlaşdırır: telefon, planşet, qatlanan, ChromeOS. En sinifləri: COMPACT (0–600 dp), MEDIUM (600–840 dp), EXPANDED (>840 dp). Hündürlük sinifləri: COMPACT (0–480 dp), MEDIUM (480–900 dp), EXPANDED (>900 dp).

SwiftUI-də Adaptive Layout

SwiftUI Size Classes-dan birbaşa istifadə etmədən adaptiv layout üçün daxili alətlər təqdim edir. AnyLayout, ViewThatFits və GeometryReader mövcud məkana avtomatik uyğunlaşan interfeyslər qurmağa imkan verir.

swift
// AnyLayout və ViewThatFits vasitəsilə SwiftUI adaptasiyası
import SwiftUI

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

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

        layout {
            Label("Seçilmişlər", systemImage: "star")
            Label("Son", systemImage: "clock")
            Label("Parametrlər", systemImage: "gear")
        }
        .padding()
    }
}

// ViewThatFits — layout-un avtomatik seçimi
struct SmartLayout: View {
    var body: some View {
        ViewThatFits {
            HStack { // Prioritet 1: üfüqi
                CardView()
                CardView()
            }
            VStack { // Sığmazsa — şaquli
                CardView()
                CardView()
            }
        }
    }
}

ViewThatFits — SwiftUI-nin güclü aləti, kəsilmədən mövcud məkana sığan ilk uşaq view-i avtomatik seçir. Bu, sadə adaptiv keçidlər üçün Size Classes-ı açıq şəkildə yoxlamaq ehtiyacını aradan qaldırır. AnyLayout view-in gövdəsində if-else olmadan layout növünü (HStack/VStack) dəyişməyə imkan verir.

Jetpack Compose-da Adaptive Layout

Jetpack Compose adaptiv düzən üçün WindowSizeClass (Material 3 adaptive kitabxanasından) və BoxWithConstraints istifadə edir. XML kvalifikatorlarından fərqli olaraq, Compose pəncərə ölçüsünü runtime-da təyin edir və konfiqurasiya dəyişdikdə UI-ni reaktiv şəkildə yenidən qurur.

kotlin
// BoxWithConstraints vasitəsilə Jetpack Compose adaptasiyası
@Composable
fun AdaptiveList(items: List<String>) {
    BoxWithConstraints {
        val width = maxWidth

        if (width >= 600.dp) {
            // Planşet: iki sütun (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: naviqasiya ilə bir sütun
            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 hazır komponentlər təqdim edir: ListDetailScaffold, SupportingPaneScaffold, NavigationSuiteScaffold. Bu komponentlər avtomatik olaraq WindowWidthSizeClass-a uyğunlaşır — stacked (COMPACT) və side-by-side (MEDIUM/EXPANDED) arasında keçid edir. Proqramçı yalnız nümunə seçməli və məzmun panellərini ötürməlidir.

Tez-tez verilən suallar

sw600dp və w600dp arasında fərq nədir?

sw600dp (smallestWidth) — oriyentasiyadan asılı olmayaraq minimum ekran eni. Həmişə 7"+ planşetlərdə işləyir. w600dp (available width) — cari oriyentasiyanı nəzərə alan əlçatan en. Eni 600 dp-dən çox ola bilən landşaftdakı telefonlarda işləyir.

iOS-da UITraitCollection nədir?

UITraitCollection — mühit xüsusiyyətlərini ehtiva edən iOS obyekti: size classes (horizontal/vertical), display scale, force touch capability, user interface idiom (iPhone/iPad), color gamut, accessibility settings. UIApplication-dan view iyerarxiyası ilə ötürülür və oriyentasiya və ya pəncərə ölçüsü dəyişdikdə yenilənir.

Tətbiqi qatlanan cihazlara necə uyğunlaşdırmaq olar?

Jetpack WindowManager (Android) və UIScreen nativeBounds + traitCollection (iOS) istifadə edin. Qatlanan cihazlar açıldıqda Size Class-ı dəyişir. Activity-ni yenidən başlatmadan pəncərə ölçüsü dəyişikliklərinə reaktiv abunə ilə kanonik layout (list-detail, supporting pane) əsaslı arxitektura tövsiyə olunur.

iPad üçün ayrı storyboards yaratmaq lazımdırmı?

Xeyr. Size Classes variasiyaları olan bir storyboard və ya UIKit vasitəsilə proqram layout istifadə edin. SwiftUI ümumiyyətlə storyboards tələb etmir. iPad üçün ayrı storyboards təkrarlama yaradır və dəstəyi çətinləşdirir — bir maketi Size Classes vasitəsilə uyğunlaşdırmaq daha yaxşıdır.

Material 3-də canonical layouts nədir?

Canonical layouts — Google-dan hazır adaptiv düzən nümunələri: list-detail (siyahı + təfərrüat), supporting pane (məzmun + hərəkət paneli), feed (kartlar). Hər nümunə üç vəziyyəti dəstəkləyir (compact/medium/expanded) və Material 3 Adaptive kitabxanasında ListDetailScaffold və SupportingPaneScaffold vasitəsilə tətbiq edilmişdir.

Nəticə

  • Adaptive Layout — müxtəlif cihazlar üçün breakpoint nöqtələrində maketlərin diskret dəyişdirilməsi
  • Size Classes iOS (Compact/Regular) iPhone, iPad və Split View üçün layout təyin edir
  • UITraitCollection — mühit xüsusiyyətlərini view iyerarxiyası ilə ötürmə mexanizmi
  • sw600dp — 7"+ planşetlər üçün Android minimum en kvalifikatoru
  • w600dp — landşafta fırlanma zamanı işə düşən əlçatan en kvalifikatoru
  • Jetpack WindowManager WindowSizeClass təqdim edir (WindowWidthSizeClass: COMPACT/MEDIUM/EXPANDED)
  • Material 3 Adaptive — avtomatik uyğunlaşma ilə hazır komponentlər (ListDetailScaffold)

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun