Responsive Design เป็นแนวทางการสร้างอินเทอร์เฟซที่เลย์เอาต์ปรับตัวโดยอัตโนมัติตามขนาด การวางแนว และประเภทของอุปกรณ์ ในการพัฒนามือถือ responsive design ถูกนำไปใช้ผ่าน size classes ใน iOS และ configuration qualifiers ใน Android บทความนี้กล่าวถึงหลักการของเลย์เอาต์แบบปรับตัว เครื่องมือของทั้งสองแพลตฟอร์ม และตัวอย่างโค้ด
ประเด็นสำคัญ
Responsive Design เป็นวิธีการสร้างอินเทอร์เฟซที่เลย์เอาต์ตอบสนองต่อขนาดหน้าจอ การวางแนว และพื้นที่ว่าง โดยจัดเรียงองค์ประกอบใหม่โดยไม่สูญเสียฟังก์ชันการทำงาน คำนี้ถูกบัญญัติโดย Ethan Marcotte ในปี 2010 สำหรับการออกแบบเว็บ แต่หลักการสามารถนำไปใช้กับแอปพลิเคชันมือถือแบบเนทีฟได้อย่างสมบูรณ์
ในการพัฒนามือถือ responsive design หมายความว่าแอปพลิเคชันเดียวกันจะแสดงผลอย่างถูกต้องบนอุปกรณ์ทั้งหมด ตั้งแต่ iPhone SE (375 pt) ถึง iPad Pro (1024 pt ในแนวตั้ง) และจากสมาร์ทโฟน Android (360 dp) ถึงแท็บเล็ต (800 dp) องค์ประกอบสำคัญคือ กริดที่ยืดหยุ่น รูปภาพแบบปรับตัว และ สื่อแบบสอบถาม ในระดับเฟรมเวิร์ก (size classes, qualifiers)
ตาม Apple Developer Documentation แอปพลิเคชันควรเป็นแบบสากล — ทำงานบนอุปกรณ์ทั้งหมดโดยไม่ต้องมีการสร้างแยกสำหรับ iPad Google Play แนะนำให้ใช้เลย์เอาต์แบบปรับตัวผ่าน Jetpack WindowManager และ canonical layouts การขาดการปรับตัวสำหรับแท็บเล็ตเป็นสาเหตุทั่วไปของรีวิวเชิงลบ
คำว่า responsive และ adaptive มักถูกสับสน แม้ว่าจะอธิบายแนวทางที่แตกต่างกัน Responsive design ใช้กริดที่ยืดหยุ่นซึ่งปรับเปลี่ยนอย่างต่อเนื่องตามความกว้างหน้าจอ Adaptive design ใช้เลย์เอาต์คงที่สำหรับ breakpoints ที่กำหนดไว้ล่วงหน้า — แอปพลิเคชันสลับระหว่างเลย์เอาต์เหล่านั้นอย่างฉับพลัน
| ลักษณะ | Responsive Design | Adaptive Design |
|---|---|---|
| แนวทาง | การไหลอย่างต่อเนื่อง | การสลับแบบไม่ต่อเนื่อง |
| กริด | ตามเปอร์เซ็นต์, ลื่นไหล | คงที่สำหรับแต่ละ breakpoint |
| การนำไปใช้ | Auto Layout, Flexbox, ConstraintLayout | Size Classes, layout-w600dp, storyboards แยก |
| จำนวนเลย์เอาต์การออกแบบ | หนึ่ง แต่ยืดหยุ่น | หลายแบบ (แนวตั้ง, แนวนอน, แท็บเล็ต) |
ในทางปฏิบัติ แอปมือถือใช้การผสมผสานของทั้งสองแนวทาง กริดพื้นฐานถูกสร้างขึ้นแบบ responsive (Auto Layout พพร้อมการพึ่งพา constraint) และเมื่อถึง breakpoint (เช่น ความกว้าง > 600 pt) เลย์เอาต์จะสลับไปยังเวอร์ชันปรับตัวที่มีการจัดเรียงองค์ประกอบที่แตกต่างกัน iOS ผสมผสาน Auto Layout (responsive) กับ Size Classes (adaptive) Android ผสมผสาน ConstraintLayout (responsive) กับทรัพยากร qualifier (adaptive)
Size Classes เป็นกลไกของ iOS ที่จำแนกพื้นที่หน้าจอที่มีอยู่ตามสองแกน: แนวนอนและแนวตั้ง แต่ละแกนสามารถเป็น Compact (C) หรือ Regular (R) การรวมกันให้สี่ตัวเลือกการปรับเลย์เอาต์: CR (iPhone ทั่วไปในแนวตั้ง), RR (iPad แนวตั้ง/แนวนอน), RC (iPhone แนวนอนบน Plus/Pro Max), CC (iPad Split View)
// การกำหนด Size Classes ใน Swift
import UIKit
class AdaptiveViewController: UIViewController {
override func traitCollectionDidChange(
_ previousTraitCollection: UITraitCollection?
) {
super.traitCollectionDidChange(previousTraitCollection)
adjustLayout(for: traitCollection)
}
private func adjustLayout(for traits: UITraitCollection) {
switch (traits.horizontalSizeClass, traits.verticalSizeClass) {
case (.regular, .regular):
showSplitView() // iPad — แสดง master-detail
case (.compact, .regular):
showStackedView() // iPhone แนวตั้ง — เลย์เอาต์แบบซ้อน
case (.compact, .compact):
showCompactView() // iPhone SE แนวนอน — ย่อเล็กสุด
default:
showDefaultView()
}
}
private func showSplitView() {
// การใช้ UISplitViewController หรือ HStack
}
private func showStackedView() {
// สแต็กแนวตั้งสำหรับ iPhone
}
private func showCompactView() {
// ซ่อนองค์ประกอบรอง แสดงองค์ประกอบหลัก
}
}ใน Interface Builder, Size Classes ถูกกำหนดค่าผ่านแผง "wAny hAny" — นักพัฒนาเลือกการรวมกันเฉพาะ (wRegular hRegular, wCompact hRegular) และเพิ่มความผันแปรของ constraint SwiftUI ใช้ @Environment(\.horizontalSizeClass) และ @Environment(\.verticalSizeClass) สำหรับการปรับแบบตอบสนอง — เมื่อการวางแนวหรือขนาดหน้าต่างเปลี่ยนไป SwiftUI จะวาดภาพ view ใหม่โดยอัตโนมัติ
// Size Classes ใน SwiftUI
import SwiftUI
struct ResponsiveView: View {
@Environment(\.horizontalSizeClass) private var hSizeClass
var body: some View {
if hSizeClass == .regular {
// iPad — เลย์เอาต์แนวนอนพร้อมแถบด้านข้าง
HStack {
SidebarView()
.frame(width: 300)
ContentView()
}
} else {
// iPhone — สแต็กแนวตั้งเต็มหน้าจอ
VStack {
ContentView()
}
}
}
}Configuration Qualifiers เป็นกลไกของ Android สำหรับโหลดทรัพยากรต่าง ๆ (layout, values, drawables) ตามคุณลักษณะของอุปกรณ์ ตัวระบุประกอบด้วยขนาดหน้าจอ (small, normal, large, xlarge) การวางแนว (port, land) ความกว้างขั้นต่ำ (sw<N>dp) ความกว้างที่ใช้ได้ (w<N>dp) และความสูง (h<N>dp)
// การตรวจจับการกำหนดค่าอุปกรณ์ใน Kotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val config = resources.configuration
val screenWidthDp = config.screenWidthDp
val screenHeightDp = config.screenHeightDp
val orientation = config.orientation
when {
screenWidthDp >= 900 -> setContentView(R.layout.activity_main_tablet)
screenWidthDp >= 600 -> setContentView(R.layout.activity_main_sw600)
else -> setContentView(R.layout.activity_main_phone)
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, LandscapeFragment())
.commit()
}
}
}โครงสร้างทรัพยากรสำหรับหน้าจอต่าง ๆ: res/layout/activity_main.xml (โทรศัพท์), res/layout-sw600dp/activity_main.xml (แท็บเล็ต 7"), res/layout-sw720dp/activity_main.xml (แท็บเล็ต 10") Android เลือกเลย์เอาต์ที่ถูกต้องโดยอัตโนมัติตาม smallestWidth — ความกว้างหน้าจอขั้นต่ำใน dp โดยไม่ขึ้นกับการวางแนว ตัวระบุ sw<N>dp เป็นวิธีการปรับตัวที่เสถียรที่สุด
// Jetpack Compose — WindowSizeClass สำหรับการปรับตัว
@Composable
fun ResponsiveScreen() {
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
when {
windowSizeClass.windowSizeClass == WindowWidthSizeClass.EXPANDED -> {
TabletLayout() // >= 840 dp
}
windowSizeClass.windowSizeClass == WindowWidthSizeClass.MEDIUM -> {
MediumLayout() // 600–840 dp
}
else -> {
CompactLayout() // < 600 dp
}
}
}Jetpack WindowManager (ไลบรารี androidx.window) ให้ WindowSizeClass พร้อมสามประเภทความกว้าง: COMPACT (0–600 dp), MEDIUM (600–840 dp), EXPANDED (>840 dp) นี่เป็นทางเลือกสมัยใหม่แทนโฟลเดอร์ qualifier แบบเก่า Google แนะนำให้ใช้สำหรับการปรับตัวกับอุปกรณ์พับได้และแท็บเล็ต
กริดแบบปรับตัวเป็นพื้นฐานของ responsive design แทนที่ขนาดคงที่ องค์ประกอบใช้อัตราส่วนเปอร์เซ็นต์ constraints ที่ยืดหยุ่น และขนาดเนื้อหาภายใน Breakpoints คือจุดความกว้างหน้าจอที่เลย์เอาต์สลับระหว่างสถานะ
| Breakpoint | iOS Size Class | Android Qualifier | ประเภทอุปกรณ์ |
|---|---|---|---|
| 0–374 pt / dp | Compact width | — | iPhone SE, Android รุ่นเก่า |
| 375–599 pt / dp | Compact width | sw320dp | iPhone 14, Galaxy S24 |
| 600–839 pt / dp | Regular width | sw600dp | iPad mini, แท็บเล็ต 7" |
| 840+ pt / dp | Regular width | sw720dp | iPad Pro, แท็บเล็ต 10" |
Breakpoints ที่แนะนำจาก Google Material Design และ Apple HIG: 0–599 dp (โทรศัพท์, หนึ่งคอลัมน์), 600–839 dp (แท็บเล็ต, สองคอลัมน์, navigation rail), 840+ dp (แท็บเล็ต, สามคอลัมน์, navigation drawer) จำนวน breakpoints ไม่ควรเกิน 4 — จุดเปลี่ยนผ่านที่มากเกินไปทำให้การบำรุงรักษาและการทดสอบซับซ้อน
Responsive design ที่ประสบความสำเร็จต้องปฏิบัติตามชุดกฎที่พัฒนาขึ้นโดยชุมชนนักพัฒนา iOS และ Android ในช่วงทศวรรษที่ผ่านมา ด้านล่างนี้คือคำแนะนำสำคัญตาม Apple HIG, Google Material Design และประสบการณ์โครงการในระบบจริง
หลักการสำคัญของการออกแบบแบบปรับตัว: เนื้อหากำหนดเลย์เอาต์ ไม่ใช่ในทางกลับกัน ถ้า iPad แสดงการ์ดซ้อนเดียวกันกับ iPhone แต่เพียงยืดให้กว้างขึ้น — นั่นไม่ใช่ responsive design Responsive design คิดเลย์เอาต์ใหม่: บน iPhone — เลื่อนแนวตั้ง, บน iPad — master-detail พร้อมแถบด้านข้าง
คำถามที่พบบ่อย
Responsive Design ใช้กริดที่ยืดหยุ่นซึ่งปรับเปลี่ยนอย่างราบรื่นตามความกว้างหน้าจอ Adaptive Layout สลับระหว่างเลย์เอาต์คงที่ที่จุด breakpoint ในทางปฏิบัติ ทั้งสองแนวทางถูกรวมเข้าด้วยกัน: กริดพื้นฐานแบบ responsive + การสลับแบบปรับตัวสำหรับการเปลี่ยนแปลงครั้งใหญ่ (โทรศัพท์ vs แท็บเล็ต)
iOS ใช้สองแกน: แนวนอน (Compact/Regular) และแนวตั้ง (Compact/Regular) iPhone ในแนวตั้ง — Compact width, Regular height (CR) iPad — Regular width, Regular height (RR) iPhone Plus/Pro Max ในแนวนอน — Regular width, Compact height (RC) นักพัฒนากำหนดความผันแปรของ constraint สำหรับแต่ละการรวมกัน
sw600dp (smallestWidth 600 dp) คือตัวระบุทรัพยากร Android ที่หมายความว่าความกว้างหน้าจอขั้นต่ำของอุปกรณ์อย่างน้อย 600 dp ใช้สำหรับโหลดเลย์เอาต์ทางเลือกสำหรับแท็บเล็ต (7" ขึ้นไป) การวางแนวไม่มีผล — sw พิจารณาด้านที่เล็กที่สุดของหน้าจอ
บน iOS ใช้โปรแกรมจำลองกับ Size Classes ต่าง ๆ และ Preview ใน SwiftUI กับอุปกรณ์ขนาดต่าง ๆ บน Android — โปรไฟล์อุปกรณ์ในโปรแกรมจำลอง (Pixel 5, Pixel C, Galaxy Tab) และ Layout Validation ใน Android Studio บนทั้งสองแพลตฟอร์ม อย่าลืมทดสอบบน iPad/แท็บเล็ต Android จริงและอุปกรณ์พับได้
Canonical layouts คือรูปแบบเลย์เอาต์แบบปรับตัวพร้อมใช้จาก Google Material Design 3: list-detail, feed (ฟีดการ์ด), supporting pane (เนื้อหาหลัก + แผงการดำเนินการ) แต่ละรูปแบบมีสามรูปแบบย่อย (compact/medium/expanded) และปรับตัวให้เข้ากับ WindowSizeClass โดยอัตโนมัติ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ