Adaptive Layout: kulcsfogalmak, méretosztályok és minősítők

Szerző: IT Sectr Megjelenés: 2026-02-26 Olvasási idő: 10 perc

Adaptive Layout — egy interfész-készítési megközelítés, ahol az alkalmazás különböző elrendezéseket használ különböző típusú eszközökhöz és képernyő-tájolásokhoz. A responsive design-tól eltérően az adaptive layout előre elkészített elrendezések között vált a breakpoint pontokon. A cikk bemutatja a Size Classes-t és UITraitCollection-t iOS-ben, a sw600dp/layout-w600dp minősítőket Androidban, és gyakorlati példákat ad.

Főbb pontok

  • Adaptive Layout — az elrendezések diszkrét váltása a képernyő méretétől, tájolásától és az eszköz típusától függően
  • Size Classes iOS-ben a teret Compact vagy Regular kategóriába sorolja vízszintesen és függőlegesen
  • UITraitCollection — iOS környezeti jellemzők tárolója (méret, skála, force touch, színskála)
  • sw600dp — Android minimális szélesség minősítő táblagépekhez (7" és nagyobb)
  • layout-w600dp — rendelkezésre álló szélesség minősítő, amely akkor aktiválódik, ha elegendő hely van az aktuális tájolásban

Mi az Adaptive Layout?

Adaptive Layout — egy interfész-építési stratégia, ahol a fejlesztő külön elrendezéseket hoz létre minden eszköztípushoz, és a képernyő jellemzői alapján vált közöttük. A responsive design-tól eltérően, ahol az elemek folyamatosan áramlanak, az adaptive layout diszkrét váltásokat használ: telefon — egy elrendezés, táblagép — másik, asztali — harmadik.

Az Apple bevezette a Size Classes-t az iOS 8-ban (2014) az univerzális alkalmazásokkal együtt (universal binaries, amelyek iPhone-on és iPad-en is működnek). A Google bevezette a smallestWidth (swdp) minősítőt az Android 3.2-ben (2011). Mindkét mechanizmus ugyanazt a problémát oldja meg: adjunk a fejlesztőnek egy eszközt különböző UI-k létrehozásához különböző képernyőkhöz kódduplikáció nélkül.

A modern Apple HIG és Google Material Design ajánlások egyetértenek abban, hogy az adaptive layout kötelező az egynél több képernyőméretet támogató alkalmazásokhoz. A Google Play a táblagépekhez való adaptáció hiányát hibaként jelöli. Az App Store-nak nincs formális követelménye, de az iPad felhasználók natív élményt várnak, nem egy nyújtott iPhone alkalmazást.

iOS Size Classes és UITraitCollection

Size Classes — iOS jellemző, amely a rendelkezésre álló teret Compact vagy Regular kategóriába sorolja minden tengelyen. UITraitCollection — iOS rendszer a környezeti jellemzők továbbítására a view hierarchián keresztül: méret, képernyő skála, force touch capability, színskála (light/dark), accessibility settings.

Eszköz / TájolásHorizontalVertical
iPhone portré (minden modell)CompactRegular
iPhone Plus/Pro Max fekvőRegularCompact
iPhone SE / mini fekvőCompactCompact
iPad portréRegularRegular
iPad fekvőRegularRegular
iPad Split View (1/3 képernyő)CompactRegular

Az UITraitCollection-t a rendszer hozza létre, és az UIApplication-től az UIWindow-n keresztül minden UIView-hoz továbbítja. A tájolás vagy ablakméret változásakor (Split View) a rendszer új UITraitCollection-t generál és meghívja a traitCollectionDidChange-et. SwiftUI-ban a változásokat az Environment Values követi nyomon, és automatikusan újrarajzolja a view-t.

Adaptív elrendezés példa Swift-ben

Az adaptáció UITraitCollection segítségével UIKit-ben a trait collection változásokra való feliratkozással és az elrendezés újraépítésével valósul meg. Az alábbi példa egy kontrollert mutat, amely egy függőleges stack (iPhone) és egy split elrendezés (iPad) között vált.

swift
// Adaptív kontroller Size Classes-szal
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: oldalsáv + tartalom
        } else {
            showCompactLayout() // iPhone: lapfülek + 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
    }
}

A traitCollectionDidChange metódus minden traits változáskor meghívódik, de mi csak a horizontalSizeClass-t ellenőrizzük — a legjelentősebb mutatót az elrendezésváltáshoz. iOS 17+ ajánlott a UIViewController.horizontalSizeClass használata computed property-ként a reaktív frissítéshez anélkül, hogy feliratkoznánk a változásokra.

Android minősítők: sw600dp és w600dp

Az Android két fő szélesség-minősítőt kínál: swdp (smallestWidth) és wdp (available width). A különbség kritikus: sw — minimális képernyőszélesség tájolástól függetlenül, w — rendelkezésre álló szélesség az aktuális tájolás figyelembevételével. sw garantálja, hogy az elrendezés betöltődik egy olyan eszközhöz, amely fizikailag rendelkezik a megadott minimális szélességgel. w reagál az elforgatásra — fekvő módban aktiválhatja a w600dp-t, még akkor is, ha álló módban a szélesség 360 dp.

MinősítőFeltételEszköz példa
layout-sw600dpMinimális szélesség ≥ 600 dpiPad (768 dp), Pixel C (900 dp)
layout-w600dpAktuális szélesség ≥ 600 dpiPad Split View-ben (600 dp), telefon fekvőben
layout-landFekvő tájolásBármely eszköz vízszintesen elforgatva
layout-sw720dpMinimális szélesség ≥ 720 dpiPad Pro (833 dp), Galaxy Tab S9 (800 dp)

Erőforrás-hierarchia Androidban: res/layout/activity_main.xml (telefon), res/layout-sw600dp/activity_main.xml (7" táblagép), res/layout-w600dp-land/activity_main.xml (telefon fekvőben). Az Android kiválasztja a legspecifikusabb minősítőt, amely illeszkedik az aktuális eszközkonfigurációhoz. Megfelelő fájl hiányában az alap erőforrást használja a res/layout/-ból.

Adaptív elrendezés példa Kotlin-ban

A modern Android fejlesztés a Jetpack WindowManager-t használja az ablakméret meghatározására ahelyett, hogy közvetlenül olvasná az erőforrásokat. Ez különösen fontos a hajlítható eszközök esetében, ahol a képernyő mérete dinamikusan változhat (Galaxy Fold 6,2"-ról 7,6"-ra nyílik).

kotlin
// Adaptáció Jetpack WindowManager-en keresztül
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()
    }
}

A currentWindowAdaptiveInfo() komponens az androidx.window könyvtárból az interfészt bármilyen eszközhöz adaptálja: telefon, táblagép, hajlítható, ChromeOS. Szélességi osztályok: COMPACT (0–600 dp), MEDIUM (600–840 dp), EXPANDED (>840 dp). Magassági osztályok: COMPACT (0–480 dp), MEDIUM (480–900 dp), EXPANDED (>900 dp).

Adaptive Layout SwiftUI-ban

SwiftUI beépített eszközöket kínál az adaptív elrendezéshez a Size Classes közvetlen használata nélkül. Az AnyLayout, ViewThatFits és GeometryReader lehetővé teszik olyan interfészek építését, amelyek automatikusan alkalmazkodnak a rendelkezésre álló helyhez.

swift
// SwiftUI adaptáció AnyLayout és ViewThatFits segítségével
import SwiftUI

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

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

        layout {
            Label("Kedvencek", systemImage: "star")
            Label("Legutóbbi", systemImage: "clock")
            Label("Beállítások", systemImage: "gear")
        }
        .padding()
    }
}

// ViewThatFits — automatikus elrendezésválasztás
struct SmartLayout: View {
    var body: some View {
        ViewThatFits {
            HStack { // Prioritás 1: vízszintes
                CardView()
                CardView()
            }
            VStack { // Ha nem fér el — függőleges
                CardView()
                CardView()
            }
        }
    }
}

ViewThatFits — egy hatékony SwiftUI eszköz, amely automatikusan kiválasztja az első gyermek view-t, amely elfér a rendelkezésre álló helyen anélkül, hogy levágná. Ez kiküszöböli a Size Classes explicit ellenőrzésének szükségességét egyszerű adaptív váltásokhoz. AnyLayout lehetővé teszi az elrendezés típusának (HStack/VStack) megváltoztatását if-else nélkül a view törzsében.

Adaptive Layout Jetpack Compose-ban

Jetpack Compose a WindowSizeClass-t (a Material 3 adaptive könyvtárból) és a BoxWithConstraints-t használja az adaptív elrendezéshez. Az XML minősítőkkel ellentétben a Compose az ablakméretet futásidőben határozza meg, és reaktívan újraépíti az UI-t a konfiguráció változásakor.

kotlin
// Jetpack Compose adaptáció BoxWithConstraints segítségével
@Composable
fun AdaptiveList(items: List<String>) {
    BoxWithConstraints {
        val width = maxWidth

        if (width >= 600.dp) {
            // Táblagép: két oszlop (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: egy oszlop navigációval
            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() }
                )
            }
        }
    }
}

A Material 3 Adaptive Layouts kész komponenseket kínál: ListDetailScaffold, SupportingPaneScaffold, NavigationSuiteScaffold. Ezek a komponensek automatikusan alkalmazkodnak a WindowWidthSizeClass-hoz — a stacked (COMPACT) és side-by-side (MEDIUM/EXPANDED) között váltanak. A fejlesztőnek csak a mintát kell kiválasztania és a tartalmi paneleket átadnia.

Gyakran Ismételt Kérdések

Mi a különbség a sw600dp és w600dp között?

sw600dp (smallestWidth) — minimális képernyőszélesség tájolástól függetlenül. Mindig működik 7"+ táblagépeken. w600dp (available width) — rendelkezésre álló szélesség az aktuális tájolás figyelembevételével. Működik fekvő tájolású telefonokon, ahol a szélesség meghaladhatja a 600 dp-t.

Mi az UITraitCollection iOS-ben?

UITraitCollection — egy iOS objektum, amely környezeti jellemzőket tartalmaz: size classes (horizontal/vertical), display scale, force touch capability, user interface idiom (iPhone/iPad), color gamut, accessibility settings. Az UIApplication-től a view hierarchián keresztül továbbítódik, és a tájolás vagy ablakméret változásakor frissül.

Hogyan adaptáljam az alkalmazást hajlítható eszközökhöz?

Használja a Jetpack WindowManager-t (Android) és az UIScreen nativeBounds + traitCollection-t (iOS). A hajlítható eszközök kinyitáskor megváltoztatják a Size Class-t. A kanonikus elrendezéseken (list-detail, supporting pane) alapuló architektúra ajánlott reaktív feliratkozással az ablakméret változásaira az Activity újraindítása nélkül.

Külön storyboard-okat kell létrehozni az iPad-hez?

Nem. Használjon egy storyboard-ot Size Classes constraint variációkkal vagy programozott elrendezést UIKit-en keresztül. A SwiftUI egyáltalán nem igényel storyboard-okat. Külön storyboard-ok az iPad-hez duplikációt hoznak létre és megnehezítik a karbantartást — jobb egy elrendezést adaptálni a Size Classes segítségével.

Mik azok a canonical layout-ok a Material 3-ban?

Canonical layouts — kész adaptív elrendezési minták a Google-tól: list-detail (lista + részletek), supporting pane (tartalom + műveleti panel), feed (kártyák). Minden minta három állapotot támogat (compact/medium/expanded), és a Material 3 Adaptive könyvtárban van implementálva a ListDetailScaffold és SupportingPaneScaffold segítségével.

Összefoglalás

  • Adaptive Layout — elrendezések diszkrét váltása breakpoint pontokon különböző eszközökhöz
  • Size Classes iOS (Compact/Regular) meghatározzák az elrendezést iPhone, iPad és Split View számára
  • UITraitCollection — mechanizmus a környezeti jellemzők továbbítására a view hierarchián keresztül
  • sw600dp — Android minimális szélesség minősítő 7"+ táblagépekhez
  • w600dp — rendelkezésre álló szélesség minősítő, amely fekvő tájolásba forgatáskor aktiválódik
  • Jetpack WindowManager WindowSizeClass-t biztosít (WindowWidthSizeClass: COMPACT/MEDIUM/EXPANDED)
  • Material 3 Adaptive — kész komponensek automatikus adaptációval (ListDetailScaffold)

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is