Adaptive Layout: mga pangunahing konsepto, mga klase ng laki at mga kwalipikator

May-akda: IT Sectr Nai-publish: 2026-02-26 Oras ng pagbabasa: 10 min

Adaptive Layout — isang diskarte sa paggawa ng interface kung saan ang app ay gumagamit ng iba't ibang layout para sa iba't ibang uri ng device at oryentasyon ng screen. Hindi tulad ng responsive design, ang adaptive layout ay lumilipat sa pagitan ng mga inihandang layout sa mga breakpoint. Tinatalakay ng artikulo ang Size Classes at UITraitCollection sa iOS, mga kwalipikator na sw600dp/layout-w600dp sa Android, at nagbibigay ng mga praktikal na halimbawa.

Mga Pangunahing Punto

  • Adaptive Layout — discrete na paglipat ng layout depende sa laki ng screen, oryentasyon, at uri ng device
  • Size Classes sa iOS ay nag-uuri ng espasyo bilang Compact o Regular nang pahalang at patayo
  • UITraitCollection — lalagyan ng mga katangian ng kapaligiran ng iOS (laki, scale, force touch, color gamut)
  • sw600dp — Android na kwalipikator ng pinakamababang lapad para sa mga tablet (7" at mas malaki)
  • layout-w600dp — kwalipikator ng available na lapad na naa-activate kapag may sapat na espasyo sa kasalukuyang oryentasyon

Ano ang Adaptive Layout?

Adaptive Layout — isang estratehiya sa pagbuo ng interface kung saan ang developer ay gumagawa ng hiwalay na layout para sa bawat uri ng device at lumilipat sa pagitan ng mga ito batay sa mga katangian ng screen. Hindi tulad ng responsive design, kung saan ang mga elemento ay dumadaloy nang maayos, ang adaptive layout ay gumagamit ng discrete na paglipat: telepono — isang layout, tablet — iba pa, desktop — pangatlo.

Ipinakilala ng Apple ang Size Classes sa iOS 8 (2014) kasama ng mga universal app (universal binaries na gumagana sa parehong iPhone at iPad). Ipinakilala ng Google ang smallestWidth (swdp) na kwalipikator sa Android 3.2 (2011). Ang parehong mekanismo ay lumulutas ng parehong problema: bigyan ang developer ng tool para gumawa ng iba't ibang UI para sa iba't ibang screen nang walang pagdodoble ng code.

Ang mga modernong rekomendasyon ng Apple HIG at Google Material Design ay sumasang-ayon na ang adaptive layout ay kinakailangan para sa mga app na sumusuporta ng higit sa isang laki ng screen. Minamarkahan ng Google Play ang kakulangan ng adaptasyon para sa mga tablet bilang isang depekto. Ang App Store ay walang pormal na kinakailangan, ngunit ang mga gumagamit ng iPad ay umaasa ng isang native na karanasan, hindi isang stretched na iPhone app.

Size Classes at UITraitCollection sa iOS

Size Classes — katangian ng iOS na tumutukoy sa available na espasyo bilang Compact o Regular sa bawat axis. UITraitCollection — sistema ng iOS para sa pagpapadala ng mga katangian ng kapaligiran sa pamamagitan ng hierarchy ng view: laki, scale ng screen, force touch capability, color gamut (light/dark), accessibility settings.

Device / OryentasyonHorizontalVertical
iPhone portrait (lahat ng modelo)CompactRegular
iPhone Plus/Pro Max landscapeRegularCompact
iPhone SE / mini landscapeCompactCompact
iPad portraitRegularRegular
iPad landscapeRegularRegular
iPad Split View (1/3 screen)CompactRegular

Ang UITraitCollection ay nabuo ng system at ipinapadala mula sa UIApplication sa pamamagitan ng UIWindow patungo sa bawat UIView. Kapag nagbago ang oryentasyon o laki ng window (Split View), ang system ay gumagawa ng bagong UITraitCollection at tumatawag ng traitCollectionDidChange. Sa SwiftUI, ang mga pagbabago ay sinusubaybayan sa pamamagitan ng Environment Values at awtomatikong iginuhit muli ang view.

Halimbawa ng adaptive layout sa Swift

Ang adaptasyon sa pamamagitan ng UITraitCollection sa UIKit ay ipinapatupad sa pamamagitan ng pag-subscribe sa mga pagbabago ng trait collection at muling pagbuo ng layout. Ang halimbawa sa ibaba ay nagpapakita ng isang controller na lumilipat sa pagitan ng vertical stack para sa iPhone at split layout para sa iPad.

swift
// Adaptive controller na may 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: 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
    }
}

Ang metodo na traitCollectionDidChange ay tinatawag sa bawat pagbabago ng traits, ngunit sinusuri lang namin ang horizontalSizeClass — ang pinakamahalagang indikator para sa pagbabago ng layout. Sa iOS 17+ inirerekomenda ang paggamit ng UIViewController.horizontalSizeClass bilang computed property para sa reaktibong pag-update nang hindi nag-subscribe sa mga pagbabago.

Mga kwalipikator ng Android: sw600dp at w600dp

Ang Android ay nagbibigay ng dalawang pangunahing kwalipikator ng lapad: swdp (smallestWidth) at wdp (available width). Ang pagkakaiba ay kritikal: sw — pinakamababang lapad ng screen anuman ang oryentasyon, w — available na lapad na isinasaalang-alang ang kasalukuyang oryentasyon. sw ginagarantiyahan na ang layout ay mai-load para sa isang device na pisikal na may tinukoy na pinakamababang lapad. w ay tumutugon sa pag-ikot — sa landscape mode ay maaaring i-activate ang w600dp, kahit na sa portrait ang lapad ay 360 dp.

KwalipikatorKondisyonHalimbawa ng device
layout-sw600dpPinakamababang lapad ≥ 600 dpiPad (768 dp), Pixel C (900 dp)
layout-w600dpKasalukuyang lapad ≥ 600 dpiPad sa Split View (600 dp), telepono sa landscape
layout-landOryentasyong landscapeAnumang device na pinaikot nang pahalang
layout-sw720dpPinakamababang lapad ≥ 720 dpiPad Pro (833 dp), Galaxy Tab S9 (800 dp)

Hierarchy ng mga resource sa Android: res/layout/activity_main.xml (telepono), res/layout-sw600dp/activity_main.xml (tablet 7"), res/layout-w600dp-land/activity_main.xml (telepono sa landscape). Pinipili ng Android ang pinaka-specific na kwalipikator na akma sa kasalukuyang configuration ng device. Kung walang angkop na file, ginagamit ang base resource mula sa res/layout/.

Halimbawa ng adaptive layout sa Kotlin

Ang modernong pag-develop ng Android ay gumagamit ng Jetpack WindowManager para matukoy ang laki ng window sa halip na direktang magbasa ng mga resource. Ito ay lalong mahalaga para sa mga foldable device, kung saan ang laki ng screen ay maaaring magbago nang dynamic (Galaxy Fold ay bumubuka mula 6.2" hanggang 7.6").

kotlin
// Adaptasyon sa pamamagitan ng 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("Telepono", 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()
    }
}

Ang component na currentWindowAdaptiveInfo() mula sa androidx.window library ay umaangkop ng interface sa anumang device: telepono, tablet, foldable, ChromeOS. Mga klase ng lapad: COMPACT (0–600 dp), MEDIUM (600–840 dp), EXPANDED (>840 dp). Mga klase ng taas: COMPACT (0–480 dp), MEDIUM (480–900 dp), EXPANDED (>900 dp).

Adaptive Layout sa SwiftUI

SwiftUI ay nagbibigay ng mga built-in na tool para sa adaptive layout nang walang direktang paggamit ng Size Classes. Ang AnyLayout, ViewThatFits, at GeometryReader ay nagbibigay-daan sa pagbuo ng mga interface na awtomatikong umaangkop sa available na espasyo.

swift
// Adaptasyon ng SwiftUI sa pamamagitan ng AnyLayout at ViewThatFits
import SwiftUI

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

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

        layout {
            Label("Paborito", systemImage: "star")
            Label("Kamakailan", systemImage: "clock")
            Label("Mga Setting", systemImage: "gear")
        }
        .padding()
    }
}

// ViewThatFits — awtomatikong pagpili ng layout
struct SmartLayout: View {
    var body: some View {
        ViewThatFits {
            HStack { // Priyoridad 1: pahalang
                CardView()
                CardView()
            }
            VStack { // Kung hindi kasya — patayo
                CardView()
                CardView()
            }
        }
    }
}

ViewThatFits — isang makapangyarihang tool ng SwiftUI na awtomatikong pumipili ng unang child view na kasya sa available na espasyo nang hindi pinuputol. Ito ay nag-aalis ng pangangailangan na suriin nang tahasan ang Size Classes para sa simpleng adaptive na paglipat. AnyLayout ay nagpapahintulot sa pagpapalit ng uri ng layout (HStack/VStack) nang walang if-else sa body ng view.

Adaptive Layout sa Jetpack Compose

Jetpack Compose ay gumagamit ng WindowSizeClass (mula sa Material 3 adaptive library) at BoxWithConstraints para sa adaptive na layout. Hindi tulad ng XML na mga kwalipikator, tinutukoy ng Compose ang laki ng window sa runtime at reaktibong binubuo muli ang UI kapag nagbago ang configuration.

kotlin
// Adaptasyon ng Jetpack Compose sa pamamagitan ng BoxWithConstraints
@Composable
fun AdaptiveList(items: List<String>) {
    BoxWithConstraints {
        val width = maxWidth

        if (width >= 600.dp) {
            // Tablet: dalawang column (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 {
            // Telepono: isang column na may nabigasyon
            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() }
                )
            }
        }
    }
}

Ang Material 3 Adaptive Layouts ay nagbibigay ng mga ready-made na component: ListDetailScaffold, SupportingPaneScaffold, NavigationSuiteScaffold. Ang mga component na ito ay awtomatikong umaangkop sa WindowWidthSizeClass — lumilipat sa pagitan ng stacked (COMPACT) at side-by-side (MEDIUM/EXPANDED). Ang developer ay kailangan lang pumili ng pattern at magbigay ng mga content panel.

Mga Madalas Itanong

Ano ang pagkakaiba ng sw600dp at w600dp?

sw600dp (smallestWidth) — pinakamababang lapad ng screen anuman ang oryentasyon. Palaging gumagana sa mga tablet na 7"+. w600dp (available width) — available na lapad na isinasaalang-alang ang kasalukuyang oryentasyon. Gumagana sa mga telepono sa landscape, kung saan ang lapad ay maaaring lumampas sa 600 dp.

Ano ang UITraitCollection sa iOS?

UITraitCollection — object ng iOS na naglalaman ng mga katangian ng kapaligiran: size classes (horizontal/vertical), display scale, force touch capability, user interface idiom (iPhone/iPad), color gamut, accessibility settings. Ito ay ipinapadala mula sa UIApplication sa pamamagitan ng hierarchy ng view at nagbabago kapag nagbago ang oryentasyon o laki ng window.

Paano iangkop ang app para sa mga foldable device?

Gamitin ang Jetpack WindowManager (Android) at UIScreen nativeBounds + traitCollection (iOS). Ang mga foldable device ay nagbabago ng Size Class kapag binuksan. Inirerekomenda ang arkitektura batay sa canonical layout (list-detail, supporting pane) na may reaktibong pag-subscribe sa mga pagbabago ng laki ng window nang hindi nire-restart ang Activity.

Kailangan bang gumawa ng hiwalay na storyboards para sa iPad?

Hindi. Gumamit ng isang storyboard na may Size Classes constraint variations o programmatic layout sa pamamagitan ng UIKit. Ang SwiftUI ay hindi nangangailangan ng storyboards. Ang hiwalay na storyboards para sa iPad ay lumilikha ng pagdodoble at nagpapahirap sa pagpapanatili — mas mainam na iangkop ang isang layout sa pamamagitan ng Size Classes.

Ano ang canonical layouts sa Material 3?

Canonical layouts — mga ready-made na pattern ng adaptive layout mula sa Google: list-detail (listahan + detalye), supporting pane (nilalaman + action panel), feed (cards). Bawat pattern ay sumusuporta sa tatlong estado (compact/medium/expanded) at ipinatupad sa Material 3 Adaptive library sa pamamagitan ng ListDetailScaffold at SupportingPaneScaffold.

Buod

  • Adaptive Layout — discrete na paglipat ng layout sa mga breakpoint para sa iba't ibang device
  • Size Classes iOS (Compact/Regular) ay tumutukoy ng layout para sa iPhone, iPad at Split View
  • UITraitCollection — mekanismo ng pagpapadala ng mga katangian ng kapaligiran sa pamamagitan ng hierarchy ng view
  • sw600dp — Android na kwalipikator ng pinakamababang lapad para sa mga tablet na 7"+
  • w600dp — kwalipikator ng available na lapad na naa-activate kapag umikot sa landscape
  • Jetpack WindowManager ay nagbibigay ng WindowSizeClass (WindowWidthSizeClass: COMPACT/MEDIUM/EXPANDED)
  • Material 3 Adaptive — mga ready-made na component na may awtomatikong adaptasyon (ListDetailScaffold)

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din