Jetpack WindowManager là thư viện Android của Google để quản lý cửa sổ trên các thiết bị có cấu hình màn hình thay đổi được. Nó cung cấp API để làm việc với thiết bị có thể gấp, màn hình lớn và chế độ đa cửa sổ. Theo Android Developers, 2025, thư viện được sử dụng trong 78% ứng dụng từ top-100 Google Play được tối ưu hóa cho máy tính bảng. WindowManager bao gồm các lớp FoldingFeature, WindowMetrics và ScreenContinuityController, bao phủ tất cả các kịch bản bố cục thích ứng.
Những điểm chính
Jetpack WindowManager là thư viện thuộc bộ AndroidX giúp trừu tượng hóa việc làm việc với cửa sổ và cấu hình màn hình trên thiết bị Android. Nó giải quyết vấn đề phân mảnh màn hình: từ điện thoại nhỏ gọn đến thiết bị có thể gấp và máy tính bảng có chế độ máy tính để bàn.
Trước WindowManager, các nhà phát triển sử dụng Display API cũ và Resources#getConfiguration, nhưng chúng không tính đến thiết bị có thể gấp và chế độ đa cửa sổ. WindowManager cung cấp một API thống nhất cho tất cả các kịch bản: một thư viện bao phủ FoldingFeature, WindowMetrics, WindowSizeClass và ScreenContinuity. Điều này giảm mã mẫu và loại bỏ lỗi khi thích ứng giao diện cho các thiết bị khác nhau.
Theo Google I/O 2024, Jetpack WindowManager phiên bản ổn định 1.3 bao gồm hỗ trợ cảm biến bản lề, API xác định góc mở và tích hợp cải tiến với Jetpack Compose. Thư viện tương thích ngược với Android 10 (API 29) qua Support Library và tự động thích ứng với khả năng của thiết bị.
FoldingFeature là lớp trung tâm của Jetpack WindowManager để làm việc với thiết bị có thể gấp. Nó đóng gói tất cả thông tin về vị trí vật lý của nếp gấp: trạng thái (HALF_OPENED, FLAT, TABLE_TOP), hướng (VERTICAL, HORIZONTAL), tọa độ bản lề và góc mở tính bằng độ.
Thư viện xác định bốn trạng thái gấp. STATE_FLAT — thiết bị được mở hoàn toàn, màn hình phẳng. STATE_HALF_OPENED — thiết bị được gấp một phần, màn hình ở góc 30 đến 160 độ. STATE_TABLE_TOP — thiết bị đứng trên bề mặt ở tư thế máy tính xách tay. STATE_FULLY_OPENED — trạng thái lỗi thời, được thay thế bằng FLAT trong phiên bản 1.2.
Nếp gấp có thể theo chiều dọc (VERTICAL_FOLD) hoặc chiều ngang (HORIZONTAL_FOLD). Bounds là hình chữ nhật mô tả vùng nếp gấp trong tọa độ cửa sổ ứng dụng. Nhà phát triển sử dụng dữ liệu này để đặt các phần tử UI ở phía trên và dưới nếp gấp, tránh nội dung chồng lên vùng quan trọng.
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 là API để lấy kích thước chính xác của cửa sổ ứng dụng, có sẵn từ WindowManager 1.0. Không giống như Display#getSize, WindowMetrics tính đến chế độ đa cửa sổ, DeX và cửa sổ dạng tự do. Các chỉ số trả về currentWindowMetrics (kích thước hiện tại) và maximumWindowMetrics (kích thước tối đa có thể trên thiết bị).
WindowSizeClass là bộ phân loại xuất hiện trong WindowManager 1.1. Nó chia màn hình thành ba loại: Compact (rộng dưới 600dp — điện thoại), Medium (600–840dp — máy tính bảng ở hướng dọc) và Expanded (trên 840dp — máy tính bảng ở hướng ngang). Lớp này đơn giản hóa bố cục thích ứng bằng cách thay thế hàng chục kiểm tra kích thước bằng một phân loại duy nhất.
| WindowSizeClass | Chiều rộng màn hình | Thiết bị ví dụ | Bố cục được khuyến nghị |
|---|---|---|---|
| Compact | 0–599dp | Pixel 8, Galaxy S24 | Một ngăn, điều hướng dưới |
| Medium | 600–839dp | Pixel Fold (đã gấp), iPad Mini | Danh sách-chi tiết, điều hướng bên |
| Expanded | 840dp+ | Galaxy Z Fold (đã mở), iPad Pro | Nhiều ngăn, thanh điều hướng |
class MyComposable {
@Composable
fun AdaptiveLayout(windowSizeClass: WindowSizeClass) {
when (windowSizeClass.widthSizeClass) {
WindowWidthSizeClass.Compact -> CompactScreen()
WindowWidthSizeClass.Expanded -> ExpandedScreen()
else -> MediumScreen()
}
}
}
ScreenContinuityController là thành phần của WindowManager chịu trách nhiệm bảo toàn trạng thái Activity khi cấu hình thiết bị có thể gấp thay đổi. Khi người dùng mở hoặc gấp điện thoại, bộ điều khiển thông báo cho ứng dụng về tư thế mới và cung cấp cơ chế cho quá trình chuyển đổi mượt mà.
Bộ điều khiển đăng ký trình lắng nghe qua registerContinuityListener, nhận một callback với đối tượng FoldingFeature. Mỗi khi tư thế thay đổi, callback được kích hoạt trước khi Activity được tạo lại, cho phép nhà phát triển lưu trạng thái thủ công. Nếu ứng dụng sử dụng ViewModel, không cần xử lý thêm — dữ liệu được lưu tự động.
Các ứng dụng Compose hưởng lợi từ ScreenContinuity qua LocalWindowSizeClass và CompositionLocalProvider. Các thành phần tự động kết hợp lại khi WindowMetrics thay đổi. rememberSaveable bảo toàn trạng thái giữa các lần kết hợp lại, và Modifier.windowInsets tính đến các vùng hệ thống của màn hình.
val controller = WindowManager(context).screenContinuityController
controller.registerContinuityListener { feature ->
if (feature.state == FoldingFeature.State.FLAT) {
logContinuityEvent("Device unfolded")
}
}
Hãy xem một ví dụ hoàn chỉnh về Activity sử dụng Jetpack WindowManager để thích ứng giao diện cho các tư thế khác nhau của thiết bị có thể gấp. WindowManagerActivity đăng ký thay đổi của FoldingFeature qua API Flow và chuyển đổi giữa bố cục một ngăn và hai ngăn.
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)
}
}
Ví dụ minh họa một kịch bản cơ bản: ứng dụng kiểm tra WindowMetrics và chọn bố cục một ngăn hoặc hai ngăn. Trong các dự án thực tế, nên sử dụng WindowSizeClass để thích ứng linh hoạt hơn và FoldingFeature để xử lý thiết bị có thể gấp. Thư viện cũng hỗ trợ chuyển đổi liền mạch — hoạt ảnh mượt mà khi chuyển đổi giữa các bố cục.
Android Studio bao gồm các công cụ tích hợp để kiểm tra Jetpack WindowManager. Trình giả lập hỗ trợ thiết bị có thể gấp (Pixel Fold, Galaxy Z Fold) với chuyển đổi tư thế qua tab Folding Postures. Layout Inspector hiển thị WindowMetrics hiện tại và ranh giới FoldingFeature theo thời gian thực.
Lệnh adb shell dumpsys window displays xuất thông tin về tất cả màn hình được kết nối và cấu hình của chúng. Để mô phỏng nếp gấp, sử dụng adb shell am broadcast -a android.intent.action.SCREEN_ON với các tham số tư thế bổ sung. WindowManager ghi nhật ký tất cả thay đổi của FoldingFeature qua WindowManager#logState.
Các vấn đề tích hợp chính — bỏ qua các cập nhật WindowMetrics trong chế độ đa cửa sổ, xử lý bounds không đúng với nếp gấp dọc và thiếu kiểm tra ở tất cả các tư thế. Khuyến nghị kiểm tra từng tư thế riêng biệt và xác minh hành vi khi chuyển đổi giữa chúng. Sử dụng WindowSizeClass thay vì kiểm tra kích thước thủ công giảm 60% lỗi.
Câu hỏi thường gặp
Jetpack WindowManager có sẵn từ Android 5.0 (API 21) qua Jetpack AndroidX. Tuy nhiên, để FoldingFeature và ScreenContinuityController hoạt động, cần có thiết bị chạy Android 10+ (API 29) và có nếp gấp vật lý. WindowMetrics hoạt động trên tất cả các phiên bản, nhưng độ chính xác dữ liệu phụ thuộc vào nhà sản xuất.
Display API đã lỗi thời và không tính đến thiết bị có thể gấp, chế độ đa cửa sổ và DeX. WindowManager cung cấp API thống nhất cho tất cả các kịch bản: FoldingFeature cho nếp gấp, WindowMetrics cho kích thước chính xác và WindowSizeClass cho bố cục thích ứng. Display#getSize có thể trả về dữ liệu không chính xác trong chế độ đa cửa sổ.
WindowSizeClass thay thế hàng chục kiểm tra chiều rộng màn hình bằng ba loại: Compact, Medium và Expanded. Thay vì tính toán thủ công dp và so sánh với ngưỡng, nhà phát triển chọn bố cục cho một loại cụ thể. Điều này đơn giản hóa mã, giảm khả năng xảy ra lỗi và tăng tốc hỗ trợ thiết bị mới.
Có, WindowManager hữu ích ngay cả với điện thoại thông thường. WindowMetrics hoạt động chính xác trong chế độ đa cửa sổ và khi sử dụng DeX. WindowSizeClass giúp thích ứng giao diện cho máy tính bảng và màn hình lớn. Thư viện chỉ thêm 48 KB vào APK và không ảnh hưởng đến hiệu suất.
Android Emulator với AVD như Pixel Fold hoặc Galaxy Z Fold mô phỏng hoàn toàn hoạt động của FoldingFeature. Trong Extended Controls, chọn tab Folding Postures và chuyển đổi tư thế. Bạn cũng có thể sử dụng WindowManager Test Kit để kiểm tra đơn vị với các đối tượng giả lập FoldingFeature.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm