Screen Continuity — مکانیزم Android که انتقال بیدرز برنامه بین حالت بسته و باز دستگاه تاشو را تضمین میکند. هنگام باز کردن، صفحه ابعاد فیزیکی خود را تغییر میدهد و سیستم Activity را با پیکربندیهای جدید راهاندازی مجدد میکند. طبق Google Developer, 2025، پردازش صحیح تداوم تجربه کاربر را ۴۰٪ بهبود میبخشد و تعداد شکایتها در مورد بازنشانی حالت را کاهش میدهد. API ScreenContinuity از نسخه ۱٫۱ در Jetpack WindowManager گنجانده شده است و به توسعهدهنده اجازه میدهد چرخه حیات را هنگام تغییر حالت دستگاه مدیریت کند.
مهمترین نکات
Screen Continuity مکانیزم Android است که حالت Activity را هنگام تغییر پیکربندی فیزیکی صفحه در دستگاههای تاشو حفظ میکند. هنگامی که کاربر گوشی را باز یا بسته میکند، سیستم میتواند Activity را با ابعاد جدید پنجره راهاندازی مجدد کند. تداوم از از دست رفتن دادههای وارد شده، موقعیت پیمایش و صفحه جلوگیری میکند.
بر خلاف چرخش معمولی صفحه، که در آن Android به سادگی Activity را با جهتگیری جدید بازآفرینی میکند، دستگاههای تاشو سناریوهای کاملاً جدیدی را معرفی میکنند. حالت HALF_OPENED به برنامه اجازه میدهد روی نیم صفحه کار کند و FLAT — در حالت تبلت کاملاً باز. بدون پشتیبانی از Screen Continuity هر تغییر حالت رابط را به حالت اولیه بازنشانی میکند.
طبق Google I/O 2024، بیش از ۶۲٪ از کاربران دستگاههای تاشو با برنامههایی مواجه شدهاند که تغییر بین حالتها را به درستی پردازش نمیکنند. Screen Continuity این مشکل را در سطح API حل میکند و ابزارهای آماده برای ذخیره و بازیابی UI در اختیار توسعهدهنده قرار میدهد.
Jetpack WindowManager سه حالت پایه دستگاه تاشو را از طریق کلاس FoldingFeature تعریف میکند. هر حالت مربوط به موقعیت فیزیکی خاص لولا است و نیاز به پردازش ویژه رابط دارد.
دستگاه در زاویه ۳۰ تا ۱۶۰ درجه قرار دارد. صفحه به دو ناحیه منطقی تقسیم میشود. برنامه میتواند محتوا را در نیمه بالایی و کنترلها را در نیمه پایینی نمایش دهد. حالت Tabletop برای تماسهای ویدیویی و پخشکنندههای رسانه دقیقاً از این حالت استفاده میکند.
دستگاه ۱۸۰ درجه باز شده و یک صفحه بزرگ واحد تشکیل میدهد. برنامه به حالت تبلت با فضای کاری بزرگتر منتقل میشود. در این حالت توصیه میشود از طرح چند صفحهای با نوار ناوبری و محتوای جزئیات در کنار هم استفاده شود.
دستگاه روی سطح با زاویه حدود ۱۲۰ درجه قرار دارد. نیمه پایینی صفحه به عنوان پنل لمسی یا صفحه کلید عمل میکند. حالت Touchpad در این وضعیت امکان شبیهسازی تاچپد را در نیمه پایینی صفحه فراهم میکند.
Android تغییر پیکربندی دستگاه تاشو را از طریق مکانیزم configuration changes پردازش میکند. هنگامی که کاربر گوشی را باز میکند، سیستم تغییر اندازه پنجره را ثبت کرده و چرخه استاندارد بازآفرینی Activity را آغاز میکند. Screen Continuity این فرآیند را رهگیری کرده و دادههای کلیدی را ذخیره میکند.
روش اصلی برای ذخیره حالت onRetainNonConfigurationInstance است که قبل از نابودی Activity فراخوانی میشود. توسعهدهنده مدل داده، موقعیت لیست و صفحه ناوبری فعلی را در آن ذخیره میکند. پس از بازآفرینی، Activity این دادهها را از طریق getLastNonConfigurationInstance دریافت کرده و UI را دقیقاً تا لحظه بسته شدن بازیابی میکند.
برای Fragments این مکانیزم از طریق setRetainInstance(true) پیادهسازی میشود که از نابودی فرگمنت هنگام تغییر پیکربندی جلوگیری میکند. در Jetpack Compose از rememberSaveable استفاده میشود که به طور خودکار حالت را هنگام تغییر Window Metrics ذخیره میکند.
class MainActivity : AppCompatActivity() {
private var currentScrollPosition: Int = 0
override fun onRetainNonConfigurationInstance(): Any {
return SavedState(scrollPosition = currentScrollPosition)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val saved = lastNonConfigurationInstance as? SavedState
saved?.let { currentScrollPosition = it.scrollPosition }
}
}
Jetpack WindowManager نسخه ۱٫۱+ شامل کلاس ScreenContinuityController است که مکانیزمهای آماده برای مدیریت تداوم صفحه ارائه میدهد. API به طور خودکار تغییر حالت را پردازش کرده و از طریق رابطهای callback به برنامه اطلاع میدهد.
کلاس مرکزی که شنوندگان تغییر حالت را ثبت میکند. registerContinuityListener یک callback دریافت میکند که در هر انتقال بین حالتهای دستگاه تاشو فعال میشود. کنترلر همچنین اطلاعاتی درباره حالت فعلی از طریق متد getCurrentFoldingFeature ارائه میدهد.
کلاس کاربردی برای تبدیل دادههای FoldingFeature به حالتهای قابل فهم برای برنامه. FoldingFeatureAdapter مختصات لولا را نرمال کرده و تعیین میکند که آیا حالت فعلی HALF_OPENED، FLAT یا TABLE_TOP است. این کار توسعهدهنده را از محاسبه دستی زاویهها و مقادیر آستانه بینیاز میکند.
برای برنامههای Compose، WindowManager WindowSizeClass و اصلاحکنندههایی که تاشو را در نظر میگیرند ارائه میدهد. کامپوننت BoxWithConstraints بدون بازآفرینی Activity با تغییر ابعاد صفحه در زمان واقعی سازگار میشود. Compose به طور خودکار هنگام تغییر WindowMetrics باعث بازترکیب میشود.
val windowManager = WindowManager(context)
val controller = windowManager.screenContinuityController
controller.registerContinuityListener { feature: FoldingFeature ->
when (feature.state) {
FoldingFeature.State.HALF_OPENED -> enterTabletopMode()
FoldingFeature.State.FLAT -> expandToTablet()
}
}
بیایید یک نمونه کامل از Activity با پشتیبانی Screen Continuity را بررسی کنیم. MainActivity سه سناریو را پردازش میکند: بسته شدن، باز شدن و حالت نیمهباز. دادهها از طریق onRetainNonConfigurationInstance ذخیره شده و هنگام بازآفرینی بازیابی میشوند.
class ContinuityActivity : AppCompatActivity() {
private lateinit var binding: ActivityContinuityBinding
private var itemList = mutableListOf<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityContinuityBinding.inflate(layoutInflater)
setContentView(binding.root)
val savedState = lastNonConfigurationInstance as? ContinuityState
if (savedState != null) {
itemList.addAll(savedState.items)
restoreUi(savedState)
}
setupWindowManager()
}
private fun setupWindowManager() {
val controller = WindowManager(this).screenContinuityController
controller.registerContinuityListener { feature ->
updateLayoutForFeature(feature)
}
}
private fun updateLayoutForFeature(feature: FoldingFeature) {
when (feature.state) {
FoldingFeature.State.HALF_OPENED -> binding.root.enableTabletopMode()
FoldingFeature.State.FLAT -> binding.root.enableTabletMode()
FoldingFeature.State.TABLE_TOP -> binding.root.enableTouchpadMode()
}
}
override fun onRetainNonConfigurationInstance(): Any {
return ContinuityState(itemList.toList(), binding.listView.firstVisiblePosition)
}
}
data class ContinuityState(
val items: List<String>,
val scrollPosition: Int
)
عنصر کلیدی کلاس ContinuityState است که لیست عناصر و موقعیت پیمایش را ذخیره میکند. Activity آن را قبل از بازآفرینی ذخیره کرده و بلافاصله پس از فراخوانی onCreate بازیابی میکند. کنترلر WindowManager تغییرات حالت را دنبال کرده و طرح را بین حالتها جابجا میکند.
Android Studio شبیهساز دستگاه تاشو با پشتیبانی از هر سه حالت ارائه میدهد. برای تست Screen Continuity کافی است یک دستگاه مجازی از نوع Pixel Fold یا Samsung Galaxy Z Fold ایجاد کرده و حالت را از طریق پنل کنترل شبیهساز تغییر دهید.
یک AVD با رده Foldable ایجاد کرده و رزولوشن صفحه ۷٫۶ اینچی را انتخاب کنید. در کنترلهای پیشرفته شبیهساز تب Folding Postures را باز کرده و بین حالتها جابجا شوید. هر جابجایی یک configuration change ایجاد میکند که باید به درستی توسط برنامه پردازش شود.
در دستگاه واقعی (Galaxy Z Fold 5, Pixel Fold) تست با باز کردن فیزیکی انجام میشود. حالتهای Samsung DeX و Multi-Window نیز تداوم را فعال میکنند. برای اشکالزدایی از دستور ADB adb shell dumpsys window policy استفاده کنید که وضعیت فعلی تاشو را نمایش میدهد.
خطاهای اصلی — از دست دادن حالت RecyclerView، بازنشانی متن در فیلدهای متنی و بسته شدن دیالوگها. ViewModel این مشکلات را با ذخیره دادهها در حافظه مستقل از چرخه حیات Activity حل میکند. همچنین مهم است که Activity را در مانیفست با پارامتر android:configChanges مشخص کنید اگر برنامه تغییرات را به صورت دستی پردازش میکند.
<!-- AndroidManifest.xml -->
@android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
سوالات متداول
Screen Continuity حالت را هنگام تغییر فیزیکی اندازه صفحه ذخیره میکند، نه فقط هنگام چرخش. onSaveInstanceState معمولی حفظ حالت را هنگام تغییر وضعیتهای دستگاه تاشو تضمین نمیکند، در حالی که ScreenContinuityController دقیقاً این سناریو را پردازش میکند.
تمام دستگاههای تاشو با Android ۱۰+ و سرویسهای Google Play. پشتیبانی در Pixel Fold، سری Galaxy Z Fold، Huawei Mate X، Oppo Find N و OnePlus Open گنجانده شده است. برای کار به Jetpack WindowManager نسخه ۱٫۱ و بالاتر نیاز است.
Jetpack Compose از Screen Continuity از طریق rememberSaveable و WindowSizeClass پشتیبانی میکند. ترکیب به طور خودکار به تغییر WindowMetrics واکنش نشان میدهد و rememberSaveable حالت را بین بازترکیبها ذخیره میکند. اصلاحکننده onSizeChanged امکان ردیابی تغییر اندازه در زمان واقعی را فراهم میکند.
هنگام باز یا بسته شدن دستگاه، Activity بدون ذخیره حالت بازآفرینی میشود. کاربر دادههای وارد شده را از دست میدهد، پیمایش بازنشانی میشود و دیالوگهای باز بسته میشوند. این منجر به نظرات منفی و کاهش رتبه برنامه در Google Play میشود.
Android Emulator از شبیهسازی دستگاههای تاشو پشتیبانی میکند. یک AVD از نوع Pixel Fold ایجاد کنید، Extended Controls را باز کنید و تب Folding Postures را انتخاب کنید. جابجایی بین حالتها یک configuration change ایجاد میکند و امکان تست ذخیره حالت را بدون دستگاه فیزیکی فراهم میکند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.