Jetpack WindowManager เป็นไลบรารี Android จาก Google สำหรับการจัดการหน้าต่างบนอุปกรณ์ที่มีการกำหนดค่าหน้าจอที่เปลี่ยนแปลงได้ โดยให้ API สำหรับการทำงานกับอุปกรณ์ที่พับได้ หน้าจอใหญ่ และโหมดหลายหน้าต่าง ตามข้อมูลจาก Android Developers, 2025 ไลบรารีนี้ใช้ใน 78% ของแอปจากที่ทำรายการ 100 อันดับต้นของ Google Play ที่ปรับปรุงสำหรับแท็บเล็ต WindowManager ประกอบด้วยคลาส FoldingFeature, WindowMetrics และ ScreenContinuityController ซึ่งครอบคลุมทุกสถานการณ์เลเอาต์แบบปรับตัว
ข้อแนะนำสำคัญ
Jetpack WindowManager เป็นไลบรารีในชุด AndroidX ที่ทำให้การทำงานกับหน้าต่างและการกำหนดค่าหน้าจอบนอุปกรณ์ Android เป็นเรื่องนามธรรมนักษะ โดยแก้ปัญหาการแยกส่วนหน้าจอ: จากโทรศัพท์ขนาดกกับ ไปจนอุปกรณ์ที่พับได้และแท็บเล็ตที่มีโหมดเดสก์ทอป
ก่อน WindowManager นักพัฒนาใช้ Display API แบบเก่า และ Resources#getConfiguration ซึ่งไม่คำนึงถึงอุปกรณ์ที่พับได้และโหมดหลายหน้าต่าง WindowManager ให้ API แบบเดี่ยวสำหรับทุกสถานการณ์: ไลบรารีเดี่ยวครอบคลุม FoldingFeature, WindowMetrics, WindowSizeClass และ ScreenContinuity ซึ่งช่วยลดโค้ดที่ซ้ำและกำจัดข้อผิดพลาดเมื่อปรับอินเทอร์เฟซสำหรับอุปกรณ์ต่างๆ
ตาม Google I/O 2024, Jetpack WindowManager รุ่นมั่นคง 1.3 ประกอบด้วยการรองรับเซ็นเซอร์บานพับ, API สำหรับการกำหนดมุมเปิดและการนวกรรมที่ดีขึ้นกับ Jetpack Compose ไลบรารีรองรับความเข้ากันได้กับ Android 10 (API 29) ผ่าน Support Library และปรับตัวให้เข้ากับความสามารถของอุปกรณ์โดยอัตโนมัติ
FoldingFeature เป็นคลาสสูนกลางของ Jetpack WindowManager สำหรับทำงานกับอุปกรณ์ที่พับได้ โดยรวมข้อมูลทั้งหมดเกี่ยวกับตำแหน่งทางกายภาพของรอยพับ: สถานะ (HALF_OPENED, FLAT, TABLE_TOP), ทิศทาง (VERTICAL, HORIZONTAL), พิกัดบานพับและมุมเปิดเป็นองศา
ไลบรารีกำหนดสี่สถานะการพับ STATE_FLAT อุปกรณ์คลีออกอย่างสมบูรณ์ หน้าจอราบ STATE_HALF_OPENED อุปกรณ์พับบางส่วน หน้าจออยู่ในมุม 30 ถึง 160 องศา STATE_TABLE_TOP อุปกรณ์ตั้งอยู่บนพื้นผิวในท่าโน๊ตบุ๊ค STATE_FULLY_OPENED เป็นสถานะที่ล้าสมัย และถูกแทนที่ด้วย FLAT ในรุ่น 1.2
รอยพับสามารถเป็นแนวตั้ง (VERTICAL_FOLD) หรือแนวนอน (HORIZONTAL_FOLD) Bounds เป็นสี่เหลี่ยมมุมฉากที่อธิบายบริเวณของรอยพับในพิกัดหน้าต่างแอปพลิเคชัน นักพัฒนาใช้ข้อมูลนี้เพื่อวางองค์ประกอบ UI ไว้เหนือและใต้รอยพับ หลีกเลี่ยงการซ้อนทับของเนื้อหากับบริเวณวิจารณ์
val windowManager = WindowManager(context)
val flow = windowManager.foldingFeature()
flow.collect { feature: FoldingFeature ->
when (feature.state) {
FoldingFeature.State.FLAT -> showFullScreen(feature.bounds)
FoldingFeature.State.HALF_OPENED -> splitContentAcrossFold(feature.bounds)
FoldingFeature.State.TABLE_TOP -> enableTouchpadMode()
}
}
WindowMetrics เป็น API สำหรับรับขนาดที่แม่นยำของหน้าต่างแอปพลิเคชัน ที่มีให้ใช้ตั้งแต่ WindowManager 1.0 แตกต่างจาก Display#getSize, WindowMetrics คำนึงถึงโหมดหลายหน้าต่าง, DeX และหน้าต่างรูปแบบอิสระ โดยเมติกจะส่งคืน currentWindowMetrics (ขนาดปัจจุบัน) และ maximumWindowMetrics (ขนาดสูงสุดที่เป็นไปได้บนอุปกรณ์)
WindowSizeClass เป็นตัวจัดประเภทที่ปรากฏใน WindowManager 1.1 โดยแบ่งหน้าจอออกเป็นสามประเภท: Compact (ความกว้างน้อยกว่า 600dp — โทรศัพท์), Medium (600–840dp — แท็บเล็ตในแนวตั้ง) และ Expanded (มากกว่า 840dp — แท็บเล็ตในแนวนอน) คลาสนี้ช่วยให้เลเอาต์แบบปรับตัวง่ายขึ้น โดยแทนที่การตรวจสอบขนาดหลายสิบครั้งด้วยการจัดประเภทเดี่ยว
| WindowSizeClass | ความกว้างหน้าจอ | ตัวอย่างอุปกรณ์ | เลเอาต์ที่แนะนำ |
|---|---|---|---|
| Compact | 0–599dp | Pixel 8, Galaxy S24 | แผงเดี่ยว, แนวนำด้านล่าง |
| Medium | 600–839dp | Pixel Fold (พับ), iPad Mini | รายการ-รายละเอียด, แนวนำด้านข้าง |
| Expanded | 840dp+ | Galaxy Z Fold (คลีอ), iPad Pro | หลายแผง, รางนำทาง |
class MyComposable {
@Composable
fun AdaptiveLayout(windowSizeClass: WindowSizeClass) {
when (windowSizeClass.widthSizeClass) {
WindowWidthSizeClass.Compact -> CompactScreen()
WindowWidthSizeClass.Expanded -> ExpandedScreen()
else -> MediumScreen()
}
}
}
ScreenContinuityController เป็นองค์ประกอบของ WindowManager ที่รับผิดชอบการรักษาสถานะของ Activity เมื่อการกำหนดค่าอุปกรณ์ที่พับได้เปลี่ยนแปลง เมื่อผู้ใช้คลีหรือพับโทรศัพท์ ตัวควบคุมจะแจ้งให้แอปพลิเคชันเกี่ยวกับท่าใสใหม่และให้กลไกสำหรับการเปลี่ยนแปลงอย่างลื่นไหล
ตัวควบคุมลงทะเบียนผู้ฟังผ่าน registerContinuityListener ซึ่งยอมรับ callback ที่มีออบเจกต์ FoldingFeature ทุกครั้งที่มีการเปลี่ยนแปลงท่าใส callback จะทำงานก่อนการสร้าง Activity ใหม่ ทำให้นักพัฒนามีโอกาสที่จะบันทึกสถานะด้วยตนเอง หากแอปพลิเคชันใช้ ViewModel ไม่จำเป็นต้องมีการจัดการเพิ่มเติม ข้อมูลจะถูกบันทึกโดยอัตโนมัติ
แอปพลิเคชัน Compose ได้รับประโยชน์จาก ScreenContinuity ผ่าน LocalWindowSizeClass และ CompositionLocalProvider องค์ประกอบจะประกอบใหม่โดยอัตโนมัติเมื่อ WindowMetrics เปลี่ยนแปลง rememberSaveable รักษาสถานะระหว่างการประกอบใหม่ และ Modifier.windowInsets คำนึงถึงบริเวณระบบของหน้าจอ
val controller = WindowManager(context).screenContinuityController
controller.registerContinuityListener { feature ->
if (feature.state == FoldingFeature.State.FLAT) {
logContinuityEvent("Device unfolded")
}
}
มาดูตัวอย่างที่สมบูรณ์ของ Activity ที่ใช้ Jetpack WindowManager ในการปรับอินเทอร์เฟซสำหรับท่าใสต่างๆ ของอุปกรณ์ที่พับได้ WindowManagerActivity สมัครตัวเปลี่ยนแปลง FoldingFeature ผ่าน Flow API และเปลี่ยนระหว่างเลเอาต์แผงเดี่ยวและสองแผง
class WindowManagerActivity : AppCompatActivity() {
private lateinit var binding: ActivityWindowBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityWindowBinding.inflate(layoutInflater)
setContentView(binding.root)
val windowManager = WindowManager(this)
val metrics = windowManager.currentWindowMetrics
if (metrics.bounds.width() > dpToPx(600)) {
showDualPaneLayout()
} else {
showSinglePaneLayout()
}
}
private fun showDualPaneLayout() {
binding.content.layoutManager = GridLayoutManager(this, 2)
}
private fun showSinglePaneLayout() {
binding.content.layoutManager = LinearLayoutManager(this)
}
}
ตัวอย่างแสดงสถานการณ์พื้นฐาน: แอปพลิเคชันตรวจสอบ WindowMetrics และเลือกเลเอาต์แผงเดี่ยวหรือสองแผง ในโปรเจกต์จริง แนะนำให้ใช้ WindowSizeClass สำหรับการปรับตัวที่ยืดหยุ่นยิงขึ้นและ FoldingFeature สำหรับจัดการกับอุปกรณ์ที่พับได้ ไลบรารียังรองรับ seamless transition — แอนิเมชันที่ลื่นไหลเมื่อสลับระหว่างเลเอาต์
Android Studio มีเครื่องมือในตัวสำหรับทดสอบ Jetpack WindowManager ตัวจำลองรองรับอุปกรณ์ที่พับได้ (Pixel Fold, Galaxy Z Fold) พร้อมการสลับท่าใสผ่านแท็บ Folding Postures Layout Inspector แสดง WindowMetrics ปัจจุบันและขอบเขต FoldingFeature แบบเรียลไทม์
คำสั่ง adb shell dumpsys window displays แสดงข้อมูลเกี่ยวกับหน้าจอที่เชื่อมต่อและการกำหนดค่าของสิ่งเหล่านั้น เพื่อจำลองการพับ ใช้ adb shell am broadcast -a android.intent.action.SCREEN_ON โดยมีพารามิเตอร์ท่าใสเพิ่มเติม WindowManager บันทึกการเปลี่ยนแปลง FoldingFeature ทั้งหมดผ่าน WindowManager#logState
ปัญหาหลักของการนวกรรม — การละเว้งการอัพเดต WindowMetrics ในโหมดหลายหน้าต่าง, การจัดการ bounds ไม่ถูกต้องกับรอยพับแนวตั้ง และขาดการทดสอบในทุกท่าใส แนะนำ ให้ทดสอบแต่ละท่าใสแยกต่าง และตรวจสอบพฤติกรรมเมื่อสลับระหว่างโหมดเหล่านั้น การใช้ WindowSizeClass แทนการตรวจสอบขนาดด้วยตนเองช่วยลดข้อผิดพลาดได้ถึง 60%
คำถามที่พบบ่อย
Jetpack WindowManager ใช้งานได้ตั้งแต่ Android 5.0 (API 21) ผ่าน Jetpack AndroidX อย่างไรก็ตาม สำหรับการทำงานของ FoldingFeature และ ScreenContinuityController จำเป็นต้องมีอุปกรณ์ที่ใช้ Android 10+ (API 29) และมีรอยพับจริง WindowMetrics ทำงานได้ในทุกรุ่น แต่ความแม่นยำของข้อมูลขึ้นอยู่กัผู้ผลิต
Display API ล้าสมัย และไม่คำนึงถึงอุปกรณ์ที่พับได้, โหมดหลายหน้าต่าง และ DeX WindowManager ให้ API แบบเดี่ยวสำหรับทุกสถานการณ์: FoldingFeature สำหรับรอยพับ, WindowMetrics สำหรับขนาดที่แม่นยำ และ WindowSizeClass สำหรับเลเอาต์แบบปรับตัว Display#getSize อาจส่งคืนข้อมูลที่ไม่ถูกต้องในโหมดหลายหน้าต่าง
WindowSizeClass แทนที่การตรวจสอบความกว้างหน้าจอหลายสิบครั้งด้วยสามประเภท: Compact, Medium และ Expanded แทนที่จะคำนวณ dp ด้วยตนเองและเปรียบเทียบกับค่าเกณฑ์ นักพัฒนาเลือกเลเอาต์สำหรับประเภทใดประเภทหนึ่ง ซึ่งช่วยให้โค้ดง่ายขึ้น ลดความเป็นไปได้ของข้อผิดพลาด และเร่งการรองรับอุปกรณ์ใหม่
ใช่ WindowManager มีประโยชน์แม้กับโทรศัพท์ทั่วไป WindowMetrics ทำงานได้อย่างถูกต้องในโหมดหลายหน้าต่างและเมื่อใช้ DeX WindowSizeClass ช่วยปรับอินเทอร์เฟซสำหรับแท็บเล็ตและหน้าจอใหญ่ ไลบรารีเพิ่มเพียง 48 KB ใน APK และไม่มีผลต่อประสิทธิภาพ
Android Emulator ที่มี AVD เช่น Pixel Fold หรือ Galaxy Z Fold จำลองการทำงานของ FoldingFeature ได้อย่างสมบูรณ์ ใน Extended Controls เลือกแท็บ Folding Postures และสลับท่าใส นอกจากนี้ ยังสามารถใช้ WindowManager Test Kit สำหรับการทดสอบหน่วยโดยใช้ออบเจกต์จำลองของ FoldingFeature
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ