Jetpack WindowManager — μια βιβλιοθήκη Android από την Google για τη διαχείριση παραθύρων σε συσκευές με μεταβαλλόμενη διαμόρφωση οθόνης. Παρέχει API για εργασία με αναδιπλούμενες συσκευές, μεγάλες οθόνες και λειτουργία multi-window. Σύμφωνα με δεδομένα των Android Developers, 2025, η βιβλιοθήκη χρησιμοποιείται στο 78% των εφαρμογών από την top-100 του Google Play που είναι βελτιστοποιημένες για tablet. Το WindowManager περιλαμβάνει τις κλάσεις FoldingFeature, WindowMetrics και ScreenContinuityController, καλύπτοντας όλα τα σενάρια προσαρμοστικής διάταξης.
Κύρια σημεία
Jetpack WindowManager — μια βιβλιοθήκη από το πακέτο AndroidX που αφαιρεί την πολυπλοκότητα εργασίας με παράθυρα και διαμορφώσεις οθόνης σε συσκευές Android. Λύνει το πρόβλημα κατακερματισμού οθονών: από συμπαγή τηλέφωνα έως αναδιπλούμενες συσκευές και tablet με λειτουργία desktop.
Πριν από την εμφάνιση του WindowManager, οι προγραμματιστές χρησιμοποιούσαν το παλιό Display API και το Resources#getConfiguration, τα οποία δεν λάμβαναν υπόψη τις αναδιπλούμενες συσκευές και τις λειτουργίες multi-window. Το WindowManager παρέχει ένα ενοποιημένο API για όλα τα σενάρια: μία βιβλιοθήκη καλύπτει τα FoldingFeature, WindowMetrics, WindowSizeClass και ScreenContinuity. Αυτό μειώνει την ποσότητα boilerplate κώδικα και εξαλείφει σφάλματα κατά την προσαρμογή της διεπαφής σε διαφορετικές συσκευές.
Σύμφωνα με το Google I/O 2024, η σταθερή έκδοση 1.3 του Jetpack WindowManager περιλαμβάνει υποστήριξη για αισθητήρες μεντεσέ, 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 — η συσκευή στέκεται σε επιφάνεια σε στάση laptop. STATE_FULLY_OPENED — παλιά κατάσταση, αντικαταστάθηκε από FLAT στην έκδοση 1.2.
Η αναδίπλωση μπορεί να είναι κατακόρυφη (VERTICAL_FOLD) ή οριζόντια (HORIZONTAL_FOLD). Bounds — ένα ορθογώνιο που περιγράφει την περιοχή αναδίπλωσης στις συντεταγμένες του παραθύρου της εφαρμογής. Ο προγραμματιστής χρησιμοποιεί αυτά τα δεδομένα για να τοποθετήσει στοιχεία διεπαφής πάνω και κάτω από την αναδίπλωση, αποφεύγοντας την επικάλυψη περιεχομένου με την κρίσιμη περιοχή.
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 λαμβάνει υπόψη τη λειτουργία multi-window, το DeX και την ελεύθερη μορφή παραθύρου. Οι μετρήσεις επιστρέφουν currentWindowMetrics (τρέχον μέγεθος) και maximumWindowMetrics (μέγιστο δυνατό μέγεθος στη συσκευή).
WindowSizeClass — ένας ταξινομητής που εμφανίστηκε στο WindowManager 1.1. Χωρίζει τις οθόνες σε τρεις κατηγορίες: Compact (πλάτος μικρότερο από 600dp — τηλέφωνο), Medium (600–840dp — tablet σε κατακόρυφο προσανατολισμό) και Expanded (πάνω από 840dp — tablet σε οριζόντιο προσανατολισμό). Αυτή η κλάση απλοποιεί την προσαρμοστική διάταξη, αντικαθιστώντας δεκάδες ελέγχους μεγέθους με μία ταξινόμηση.
| WindowSizeClass | Πλάτος οθόνης | Παράδειγμα συσκευής | Προτεινόμενη διάταξη |
|---|---|---|---|
| Compact | 0–599dp | Pixel 8, Galaxy S24 | Single-pane, bottom navigation |
| Medium | 600–839dp | Pixel Fold (διπλωμένο), iPad Mini | List-detail, side navigation |
| Expanded | 840dp+ | Galaxy Z Fold (ανοιγμένο), iPad Pro | Multi-pane, navigation rail |
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 σε λειτουργία multi-window, εσφαλμένη επεξεργασία bounds σε κατακόρυφη αναδίπλωση και έλλειψη δοκιμών σε όλες τις στάσεις. Συνιστάται η δοκιμή κάθε στάσης ξεχωριστά και ο έλεγχος συμπεριφοράς κατά την εναλλαγή μεταξύ τους. Η χρήση WindowSizeClass αντί χειροκίνητων ελέγχων μεγέθους μειώνει τον αριθμό σφαλμάτων κατά 60%.
Συχνές Ερωτήσεις
Το Jetpack WindowManager είναι διαθέσιμο από Android 5.0 (API 21) μέσω Jetpack AndroidX. Ωστόσο, για τη λειτουργία των FoldingFeature και ScreenContinuityController απαιτείται συσκευή με Android 10+ (API 29) και φυσική αναδίπλωση. Το WindowMetrics λειτουργεί σε όλες τις εκδόσεις, αλλά η ακρίβεια των δεδομένων εξαρτάται από τον κατασκευαστή.
Το Display API είναι παλιό και δεν λαμβάνει υπόψη αναδιπλούμενες συσκευές, λειτουργίες multi-window και DeX. Το WindowManager παρέχει ένα ενοποιημένο API για όλα τα σενάρια: FoldingFeature για αναδιπλώσεις, WindowMetrics για ακριβή μεγέθη και WindowSizeClass για προσαρμοστική διάταξη. Το Display#getSize μπορεί να επιστρέφει εσφαλμένα δεδομένα σε multi-window.
Το WindowSizeClass αντικαθιστά δεκάδες ελέγχους πλάτους οθόνης με τρεις κατηγορίες: Compact, Medium και Expanded. Αντί για χειροκίνητο υπολογισμό dp και σύγκριση με όρια, ο προγραμματιστής επιλέγει διάταξη για μια συγκεκριμένη κατηγορία. Αυτό απλοποιεί τον κώδικα, μειώνει την πιθανότητα σφαλμάτων και επιταχύνει την υποστήριξη νέων συσκευών.
Ναι, το WindowManager είναι χρήσιμο ακόμη και για κανονικά τηλέφωνα. Το WindowMetrics λειτουργεί σωστά σε λειτουργία multi-window και κατά τη χρήση DeX. Το WindowSizeClass βοηθά στην προσαρμογή της διεπαφής για tablet και μεγάλες οθόνες. Η βιβλιοθήκη προσθέτει μόνο 48 KB στο APK και δεν επηρεάζει την απόδοση.
Ο Android Emulator με AVD τύπου Pixel Fold ή Galaxy Z Fold προσομοιώνει πλήρως τη λειτουργία του FoldingFeature. Στο Extended Controls, επιλέξτε την καρτέλα Folding Postures και εναλλάξτε στάσεις. Μπορείτε επίσης να χρησιμοποιήσετε το WindowManager Test Kit για δοκιμές μονάδας με αντικείμενα mock FoldingFeature.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης