اندروید تمام مواد لازم را برای برنامه های پنج ستاره با صفحه نمایش بزرگ فراهم می کند. دستور العمل های موجود در این کتاب آشپزی مواد اولیه انتخابی را برای حل مشکلات توسعه خاص انتخاب و ترکیب می کنند. هر دستور غذا شامل بهترین شیوهها، نمونههای کد با کیفیت و دستورالعملهای گام به گام است که به شما کمک میکند تا به یک سرآشپز برتر صفحهنمایش بزرگ تبدیل شوید.
رتبه بندی ستاره ها
دستور العمل ها بر اساس میزان هماهنگی آنها با دستورالعمل های کیفیت برنامه های صفحه نمایش بزرگ رتبه بندی شده است.
مطابق با معیارهای سطح 1، صفحه نمایش بزرگ متمایز | |
مطابق با معیارهای سطح 2، صفحه نمایش بزرگ بهینه شده است | |
مطابق با معیارهای سطح 3، صفحه نمایش بزرگ آماده است | |
برخی از قابلیتهای صفحه نمایش بزرگ را ارائه میکند، اما از دستورالعملهای کیفیت برنامه صفحه نمایش بزرگ کوتاهی میکند | |
نیازهای یک مورد خاص را برآورده می کند، اما به درستی از صفحه نمایش بزرگ پشتیبانی نمی کند |
در Google Play توسط کاربران Chromebook مورد توجه قرار بگیرید.
اگر برنامه دوربین شما فقط با ویژگیهای اولیه دوربین کار میکند، به فروشگاههای برنامه اجازه ندهید که کاربران Chromebook را از نصب برنامه جلوگیری کنند، فقط به این دلیل که شما سهواً ویژگیهای پیشرفته دوربین موجود در تلفنهای رده بالا را مشخص کردهاید.
کرومبوکها دارای یک دوربین جلو (رو به کاربر) داخلی هستند که برای کنفرانس ویدیویی، عکسهای فوری و سایر برنامهها به خوبی کار میکند. اما همه کرومبوکها دوربین پشتی (جهانی) ندارند و اکثر دوربینهای رو به کاربر در کرومبوکها از فوکوس خودکار یا فلاش پشتیبانی نمیکنند.
برنامههای دوربین همه کاره از همه دستگاهها بدون در نظر گرفتن پیکربندی دوربین پشتیبانی میکنند - دستگاههایی با دوربین جلو، دوربین پشت، دوربینهای خارجی متصل به USB.
برای اطمینان از اینکه فروشگاههای برنامهها برنامه شما را برای بیشترین تعداد دستگاه در دسترس قرار میدهند، همیشه همه ویژگیهای دوربین استفاده شده توسط برنامهتان را اعلام کنید و صریحاً مشخص کنید که آیا این ویژگیها مورد نیاز است یا خیر.
- مجوز
CAMERA
: به برنامه شما امکان دسترسی به دوربین های دستگاه را می دهد - عنصر مانیفست
<uses-feature>
: به فروشگاه های برنامه از ویژگی های استفاده شده توسط برنامه شما اطلاع می دهد - ویژگی
required
: به فروشگاههای برنامه نشان میدهد که آیا برنامه شما میتواند بدون یک ویژگی مشخص کار کند یا خیر
مجوز CAMERA
را اعلام کنید. ویژگی های دوربین را که پشتیبانی اولیه دوربین را ارائه می دهند، اعلام کنید. مشخص کنید که آیا هر ویژگی مورد نیاز است یا خیر.
CAMERA
را اعلام کنیدمجوز زیر را به مانیفست برنامه اضافه کنید:
<uses-permission android:name="android.permission.CAMERA" />
ویژگی های زیر را به مانیفست برنامه اضافه کنید:
<uses-feature android:name="android.hardware.camera.any" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />
android:required="false"
را برای ویژگی android.hardware.camera.any
تنظیم کنید تا دستگاههایی که دارای هر نوع دوربین داخلی یا خارجی هستند یا اصلاً دوربین ندارند، به برنامه شما دسترسی داشته باشند.
برای سایر ویژگیها، android:required="false"
را تنظیم کنید تا مطمئن شوید دستگاههایی مانند Chromebook که دوربین پشتی، فوکوس خودکار یا فلاش ندارند، میتوانند به برنامه شما در فروشگاههای برنامه دسترسی داشته باشند.
کاربران Chromebook میتوانند برنامه شما را از Google Play و سایر فروشگاههای برنامه دانلود و نصب کنند. و دستگاههایی که از دوربین با ویژگیهای کامل پشتیبانی میکنند، مانند تلفنها، در عملکرد دوربین خود محدودیتی نخواهند داشت.
با تنظیم صریح ویژگیهای دوربین پشتیبانیشده توسط برنامهتان و مشخص کردن ویژگیهای مورد نیاز برنامه، برنامهتان را تا حد امکان برای دستگاههای زیادی در دسترس قرار دادهاید.
برای اطلاعات بیشتر، ویژگی های سخت افزار دوربین را در مستندات <uses-feature>
ببینید.
برنامه شما روی تلفنهایی که جهت عمودی هستند عالی کار میکند، بنابراین برنامه را فقط به حالت عمودی محدود کردهاید. اما شما فرصتی برای انجام کارهای بیشتر در صفحه نمایش های بزرگ در جهت افقی می بینید.
چگونه می توانید آن را به هر دو صورت داشته باشید - برنامه را به جهت عمودی در صفحه های کوچک محدود کنید، اما افقی را در صفحه بزرگ فعال کنید؟
بهترین برنامه ها به ترجیحات کاربر مانند جهت گیری دستگاه احترام می گذارند.
دستورالعملهای کیفیت برنامه صفحه بزرگ توصیه میکند که برنامهها از همه پیکربندیهای دستگاه، از جمله جهتهای عمودی و افقی، حالت چند پنجرهای، و حالتهای تاشده و بازشده دستگاههای تاشو پشتیبانی کنند. برنامهها باید طرحبندیها و رابطهای کاربری را برای پیکربندیهای مختلف بهینه کنند و برنامهها باید وضعیت را در طول تغییرات پیکربندی ذخیره و بازیابی کنند.
این دستور العمل یک اقدام موقتی است - کمی پشتیبانی از صفحه نمایش بزرگ. از دستور العمل استفاده کنید تا زمانی که بتوانید برنامه خود را بهبود بخشید تا از همه پیکربندیهای دستگاه پشتیبانی کامل کنید.
-
screenOrientation
: تنظیم مانیفست برنامه که به شما امکان میدهد مشخص کنید برنامه شما چگونه به تغییرات جهتگیری دستگاه پاسخ میدهد. - Jetpack WindowManager : مجموعه ای از کتابخانه ها که به شما امکان می دهد اندازه و نسبت ابعاد پنجره برنامه را تعیین کنید. سازگار با API سطح 14
-
Activity#setRequestedOrientation()
: روشی که با آن می توانید جهت برنامه را در زمان اجرا تغییر دهید
برنامه را فعال کنید تا تغییرات جهت را به طور پیش فرض در مانیفست برنامه مدیریت کند. در زمان اجرا، اندازه پنجره برنامه را تعیین کنید. اگر پنجره برنامه کوچک است، جهت گیری برنامه را با لغو تنظیمات جهت مانیفست محدود کنید.
میتوانید از اعلام عنصر screenOrientation
در مانیفست برنامه اجتناب کنید (در این صورت جهتگیری پیشفرض روی unspecified
است) یا جهتگیری صفحه را روی fullUser
تنظیم کنید. اگر کاربر چرخش مبتنی بر حسگر را قفل نکرده باشد، برنامه شما از همه جهتهای دستگاه پشتیبانی میکند.
<activity
android:name=".MyActivity"
android:screenOrientation="fullUser">
تفاوت بین استفاده از unspecified
و fullUser
ظریف اما مهم است. اگر مقدار screenOrientation
را اعلام نکنید، سیستم جهت را انتخاب میکند و خطمشی که سیستم برای تعریف جهت استفاده میکند ممکن است از دستگاهی به دستگاه دیگر متفاوت باشد. از سوی دیگر، مشخص کردن fullUser
با رفتاری که کاربر برای دستگاه تعریف کرده است مطابقت بیشتری دارد: اگر کاربر چرخش مبتنی بر حسگر را قفل کرده باشد، برنامه از اولویت کاربر پیروی می کند. در غیر این صورت، سیستم هر یک از چهار جهت گیری صفحه نمایش (عمودی، منظره، عمودی معکوس، یا منظره معکوس) را اجازه می دهد. android:screenOrientation
ببینید.
با تنظیم مانیفست برای پشتیبانی از همه جهتهای مجاز کاربر، میتوانید جهتگیری برنامه را به صورت برنامهنویسی بر اساس اندازه صفحه مشخص کنید.
کتابخانه های Jetpack WindowManager را به فایل build.gradle
یا build.gradle.kts
ماژول اضافه کنید:
implementation("androidx.window:window:version
") implementation("androidx.window:window-core:version
")
implementation 'androidx.window:window:version
' implementation 'androidx.window:window-core:version
'
از روش Jetpack WindowManager WindowMetricsCalculator#computeMaximumWindowMetrics()
برای به دست آوردن اندازه صفحه نمایش دستگاه به عنوان یک شی WindowMetrics
استفاده کنید. معیارهای پنجره را می توان با کلاس های اندازه پنجره مقایسه کرد تا تصمیم بگیرد چه زمانی جهت گیری را محدود کند.
کلاس های اندازه ویندوز نقاط شکست بین صفحه های کوچک و بزرگ را ارائه می دهند.
برای تعیین اندازه صفحه از نقاط شکست WindowWidthSizeClass#COMPACT
و WindowHeightSizeClass#COMPACT
استفاده کنید:
/** Determines whether the device has a compact screen. **/ fun compactScreen() : Boolean { val metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this) val width = metrics.bounds.width() val height = metrics.bounds.height() val density = resources.displayMetrics.density val windowSizeClass = WindowSizeClass.compute(width/density, height/density) return windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT || windowSizeClass.windowHeightSizeClass == WindowHeightSizeClass.COMPACT }
/** Determines whether the device has a compact screen. **/ private boolean compactScreen() { WindowMetrics metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this); int width = metrics.getBounds().width(); int height = metrics.getBounds().height(); float density = getResources().getDisplayMetrics().density; WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density); return windowSizeClass.getWindowWidthSizeClass() == WindowWidthSizeClass.COMPACT || windowSizeClass.getWindowHeightSizeClass() == WindowHeightSizeClass.COMPACT; }
- توجه:
- مثال های فوق به عنوان روش های یک فعالیت پیاده سازی می شوند. و بنابراین، فعالیت به
this
در آرگومانcomputeMaximumWindowMetrics()
ارجاع داده نمی شود. - روش
computeMaximumWindowMetrics()
به جایcomputeCurrentWindowMetrics()
استفاده می شود زیرا برنامه را می توان در حالت چند پنجره ای راه اندازی کرد که تنظیمات جهت صفحه را نادیده می گیرد. هیچ فایده ای برای تعیین اندازه پنجره برنامه و نادیده گرفتن تنظیمات جهت وجود ندارد، مگر اینکه پنجره برنامه کل صفحه دستگاه باشد.
برای دستورالعملهای مربوط به اعلام وابستگیها برای در دسترس قرار دادن متد computeMaximumWindowMetrics()
در برنامه خود، به WindowManager مراجعه کنید.
وقتی تشخیص دادید که دستگاه دارای اندازه صفحه نمایش فشرده است، می توانید Activity#setRequestedOrientation()
را فراخوانی کنید تا تنظیمات screenOrientation
مانیفست را لغو کنید:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) requestedOrientation = if (compactScreen()) ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else ActivityInfo.SCREEN_ORIENTATION_FULL_USER ... // Replace with a known container that you can safely add a // view to where the view won't affect the layout and the view // won't be replaced. val container: ViewGroup = binding.container // Add a utility view to the container to hook into // View.onConfigurationChanged. This is required for all // activities, even those that don't handle configuration // changes. You can't use Activity.onConfigurationChanged, // since there are situations where that won't be called when // the configuration changes. View.onConfigurationChanged is // called in those scenarios. container.addView(object : View(this) { override fun onConfigurationChanged(newConfig: Configuration?) { super.onConfigurationChanged(newConfig) requestedOrientation = if (compactScreen()) ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else ActivityInfo.SCREEN_ORIENTATION_FULL_USER } }) }
@Override protected void onCreate(Bundle savedInstance) { super.onCreate(savedInstanceState); if (compactScreen()) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER); } ... // Replace with a known container that you can safely add a // view to where the view won't affect the layout and the view // won't be replaced. ViewGroup container = binding.container; // Add a utility view to the container to hook into // View.onConfigurationChanged. This is required for all // activities, even those that don't handle configuration // changes. You can't use Activity.onConfigurationChanged, // since there are situations where that won't be called when // the configuration changes. View.onConfigurationChanged is // called in those scenarios. container.addView(new View(this) { @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (compactScreen()) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER); } } }); }
با افزودن منطق به متدهای onCreate()
و View.onConfigurationChanged()
، می توانید حداکثر معیارهای پنجره را به دست آورید و هر زمان که اندازه فعالیت تغییر کرد یا بین نمایشگرها جابه جا شد، مانند پس از چرخش دستگاه یا زمانی که تنظیم جهت گیری را لغو کنید. یک دستگاه تاشو تا شده یا باز می شود. برای اطلاعات بیشتر در مورد اینکه چه زمانی تغییرات پیکربندی رخ می دهد و چه زمانی باعث ایجاد فعالیت تفریحی می شود، به تغییرات پیکربندی دسته مراجعه کنید.
اکنون برنامه شما باید بدون توجه به چرخش دستگاه، در جهت عمودی در صفحههای کوچک باقی بماند. در صفحه نمایش های بزرگ، برنامه باید جهت گیری افقی و عمودی را پشتیبانی کند.
برای کمک به ارتقای برنامه خود برای پشتیبانی از تمام تنظیمات دستگاه، موارد زیر را ببینید:
بهینهسازی صفحه بزرگ شامل توانایی مدیریت ورودیهای صفحهکلید خارجی، مانند واکنش به فشار دادن Spacebar برای توقف یا ازسرگیری پخش ویدیوها و رسانههای دیگر است. این به ویژه برای تبلتهایی که اغلب به صفحهکلیدهای خارجی متصل میشوند و کرومبوکهایی که معمولاً با صفحهکلیدهای خارجی عرضه میشوند، اما میتوانند در حالت تبلت استفاده شوند، مفید است.
وقتی رسانه تنها عنصر پنجره است (مانند پخش ویدیوی تمام صفحه)، به رویدادهای فشار کلید در سطح فعالیت یا در Jetpack Compose در سطح صفحه پاسخ دهید.
هر زمان که برنامه شما یک فایل رسانه ای پخش می کند، کاربران باید بتوانند با فشار دادن Spacebar روی صفحه کلید فیزیکی، پخش را متوقف کرده و از سر بگیرند.
-
KEYCODE_SPACE
: کد کلید ثابت برای Spacebar.
نوشتن
-
onPreviewKeyEvent
:Modifier
که یک مؤلفه را قادر میسازد تا رویدادهای کلیدی سختافزار را هنگامی که آن (یا یکی از فرزندانش) متمرکز است، رهگیری کند. -
onKeyEvent
: مشابهonPreviewKeyEvent
، اینModifier
یک مؤلفه را قادر میسازد تا رویدادهای کلیدی سختافزار را هنگامی که آن (یا یکی از فرزندانش) متمرکز است، رهگیری کند.
بازدیدها
-
onKeyUp()
: زمانی فراخوانی می شود که یک کلید آزاد می شود و توسط یک view در یک فعالیت کنترل نمی شود.
برنامهها و برنامههای مبتنی بر نمایش مبتنی بر Jetpack Compose به فشردن کلیدهای صفحهکلید به روشهای مشابهی پاسخ میدهند: برنامه باید به رویدادهای فشار کلید گوش دهد، رویدادها را فیلتر کند و به فشارهای کلید انتخابشده مانند فشار کلید Spacebar پاسخ دهد.
بازدیدها
در یک فعالیت در برنامه خود، روش onKeyUp()
را لغو کنید:
override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { ... }
@Override public boolean onKeyUp(int keyCode, KeyEvent event) { ... }
این روش هر بار که یک کلید فشار داده میشود فراخوانی میشود، بنابراین برای هر زدن کلید دقیقاً یک بار شلیک میشود.
نوشتن
با Jetpack Compose، میتوانید از onPreviewKeyEvent
یا onKeyEvent
در صفحهای که ضربه زدن به کلید را مدیریت میکند، استفاده کنید:
Column(modifier = Modifier.onPreviewKeyEvent { event ->
if (event.type == KeyEventType.KeyUp) {
...
}
...
})
یا
Column(modifier = Modifier.onKeyEvent { event ->
if (event.type == KeyEventType.KeyUp) {
...
}
...
})
در متد onKeyUp()
یا Compose onPreviewKeyEvent
و onKeyEvent
متدهای اصلاحکننده، KeyEvent.KEYCODE_SPACE
را فیلتر کنید تا رویداد صحیح به مؤلفه رسانه شما ارسال شود:
بازدیدها
if (keyCode == KeyEvent.KEYCODE_SPACE) { togglePlayback() return true } return false
if (keyCode == KeyEvent.KEYCODE_SPACE) { togglePlayback(); return true; } return false;
نوشتن
Column(modifier = Modifier.onPreviewKeyEvent { event ->
if (event.type == KeyEventType.KeyUp && event.key == Key.Spacebar) {
...
}
...
})
یا
Column(modifier = Modifier.onKeyEvent { event ->
if (event.type == KeyEventType.KeyUp && event.key == Key.Spacebar) {
...
}
...
})
برنامه شما اکنون میتواند به فشار دادن کلید Spacebar برای توقف و ازسرگیری یک ویدیو یا رسانه دیگر پاسخ دهد.
برای کسب اطلاعات بیشتر درباره رویدادهای صفحه کلید و نحوه مدیریت آنها، به کنترل ورودی صفحه کلید مراجعه کنید.
قلم می تواند یک ابزار فوق العاده سازنده و خلاقانه در صفحه نمایش های بزرگ باشد. اما زمانی که کاربران با استفاده از قلم با یک برنامه طراحی میکنند، مینویسند یا با آن تعامل میکنند، گاهی اوقات صفحه را با کف دست لمس میکنند. قبل از اینکه سیستم رویداد را بهعنوان لمس تصادفی کف دست تشخیص دهد و آن را رد کند، میتوان رویداد لمسی را به برنامه شما گزارش داد.
برنامه شما باید رویدادهای لمسی خارجی را شناسایی کند و آنها را نادیده بگیرد. Android لمس کف دست را با ارسال یک شی MotionEvent
لغو می کند. شی را برای ACTION_CANCEL
یا ACTION_POINTER_UP
و FLAG_CANCELED
بررسی کنید تا مشخص شود که آیا حرکت ناشی از لمس کف دست را رد کنید یا خیر.
-
MotionEvent
: رویدادهای لمسی و حرکتی را نشان می دهد. حاوی اطلاعات لازم برای تعیین اینکه آیا یک رویداد باید نادیده گرفته شود یا خیر. -
OnTouchListener#onTouch()
: اشیاءMotionEvent
دریافت می کند. -
MotionEvent#getActionMasked()
: عمل مرتبط با یک رویداد حرکتی را برمیگرداند. -
ACTION_CANCEL
: ثابتMotionEvent
که نشان میدهد یک حرکت باید لغو شود. -
ACTION_POINTER_UP
: ثابتMotionEvent
که نشان میدهد نشانگر دیگری غیر از اولین نشانگر بالا رفته است (یعنی تماس با صفحه دستگاه را قطع کرده است). -
FLAG_CANCELED
: ثابتMotionEvent
که نشان میدهد بالا رفتن نشانگر باعث یک رویداد لمسی غیرعمدی شده است. به رویدادهایACTION_POINTER_UP
وACTION_CANCEL
در Android 13 (سطح API 33) و بالاتر اضافه شد.
اشیاء MotionEvent
ارسال شده به برنامه شما را بررسی کنید. از API های MotionEvent
برای تعیین ویژگی های رویداد استفاده کنید:
- رویدادهای تک اشاره ای —
ACTION_CANCEL
را بررسی کنید. در Android نسخه 13 و بالاتر،FLAG_CANCELED
را نیز بررسی کنید. - رویدادهای چند نشانگر — در Android نسخه 13 و بالاتر،
ACTION_POINTER_UP
وFLAG_CANCELED
را بررسی کنید.
به رویدادهای ACTION_CANCEL
و ACTION_POINTER_UP
/ FLAG_CANCELED
پاسخ دهید.
یک OnTouchListener
به برنامه خود اضافه کنید:
val myView = findViewById<View>(R.id.myView).apply { setOnTouchListener { view, event -> // Process motion event. } }
View myView = findViewById(R.id.myView); myView.setOnTouchListener( (view, event) -> { // Process motion event. });
ACTION_CANCEL
را بررسی کنید، که نشاندهنده یک رویداد تک نقطهای در همه سطوح API است. در Android 13 و بالاتر، ACTION_POINTER_UP
برای FLAG_CANCELED.
val myView = findViewById<View>(R.id.myView).apply { setOnTouchListener { view, event -> when (event.actionMasked) { MotionEvent.ACTION_CANCEL -> { //Process canceled single-pointer motion event for all SDK versions. } MotionEvent.ACTION_POINTER_UP -> { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && (event.flags and MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED) { //Process canceled multi-pointer motion event for Android 13 and higher. } } } true } }
View myView = findViewById(R.id.myView); myView.setOnTouchListener( (view, event) -> { switch (event.getActionMasked()) { case MotionEvent.ACTION_CANCEL: // Process canceled single-pointer motion event for all SDK versions. case MotionEvent.ACTION_UP: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && (event.getFlags() & MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED) { //Process canceled multi-pointer motion event for Android 13 and higher. } } return true; });
وقتی لمس کف دست را تشخیص دادید، میتوانید جلوههای ژست روی صفحه را لغو کنید.
برنامه شما باید تاریخچه ای از اقدامات کاربر داشته باشد تا بتوان ورودی های ناخواسته مانند لمس کف دست را لغو کرد. به عنوان مثال به اجرای یک برنامه طراحی اولیه در تقویت پشتیبانی قلم در یک کد برنامه Android مراجعه کنید.
برنامه شما اکنون میتواند لمس کف دست را برای رویدادهای چند اشارهگر در Android 13 و سطوح API بالاتر و رویدادهای تک اشارهای در همه سطوح API شناسایی و رد کند.
برای اطلاعات بیشتر به ادامه مطلب مراجعه کنید:
- ویژگیها و APIهای Android 13 - بهبود رد کف دست
- راهنمای توسعه دهندگان
- Codelab - پشتیبانی از قلم را در یک برنامه اندرویدی افزایش دهید
WebView
یک مؤلفه متداول است که یک سیستم پیشرفته برای مدیریت حالت ارائه می دهد. یک WebView
باید وضعیت خود را حفظ کند و موقعیت خود را در سراسر تغییرات پیکربندی حرکت دهد. وقتی کاربر دستگاه را میچرخاند یا یک تلفن تاشو باز میکند، WebView
میتواند موقعیت اسکرول را از دست بدهد، که کاربر را مجبور میکند دوباره از بالای WebView
به موقعیت اسکرول قبلی حرکت کند.
تعداد دفعاتی که یک WebView
دوباره ایجاد می شود را به حداقل برسانید. WebView
در مدیریت وضعیت خود خوب است و می توانید با مدیریت هر چه بیشتر تغییرات پیکربندی، از این کیفیت استفاده کنید. برنامه شما باید تغییرات پیکربندی را انجام دهد زیرا Activity
recreation (روش سیستم برای مدیریت تغییرات پیکربندی) WebView
را نیز بازسازی می کند که باعث می شود WebView
حالت خود را از دست بدهد.
-
android:configChanges
: ویژگی عنصر<activity>
مانیفست. تغییرات پیکربندی انجام شده توسط فعالیت را فهرست می کند. -
View#invalidate()
: روشی که باعث میشود یک view دوباره ترسیم شود. توسطWebView
به ارث رسیده است.
برای ذخیره وضعیت WebView
، تا آنجا که ممکن است از بازآفرینی Activity
اجتناب کنید و سپس اجازه دهید WebView
باطل شود تا بتواند با حفظ حالت خود اندازه آن را تغییر دهد.
AndroidManifest.xml
برنامه خود اضافه کنیدبا مشخص کردن تغییرات پیکربندی که توسط برنامه شما (به جای سیستم) انجام می شود، از فعالیت تفریحی خودداری کنید:
<activity
android:name=".MyActivity"
android:configChanges="screenLayout|orientation|screenSize
|keyboard|keyboardHidden|smallestScreenSize" />
WebView
باطل کنید override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) webView.invalidate() }
@Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); webview.invalidate(); }
این مرحله فقط برای سیستم view اعمال می شود، زیرا Jetpack Compose برای تغییر اندازه عناصر Composable
به درستی نیازی به بی اعتبار کردن چیزی ندارد. با این حال، Compose اغلب اگر به درستی مدیریت نشود، یک WebView
را دوباره ایجاد می کند. برای ذخیره و بازیابی حالت WebView
در برنامههای Compose خود از بستهبندی Accompanist WebView استفاده کنید.
اجزای WebView
برنامه شما اکنون وضعیت خود را حفظ میکنند و موقعیت خود را در چندین تغییر پیکربندی، از تغییر اندازه گرفته تا تغییر جهت، تا کردن و باز کردن، حفظ میکنند.
برای کسب اطلاعات بیشتر در مورد تغییرات پیکربندی و نحوه مدیریت آنها، به کنترل تغییرات پیکربندی مراجعه کنید.
RecyclerView
می تواند حجم زیادی از داده ها را با استفاده از حداقل منابع گرافیکی نمایش دهد. همانطور که یک RecyclerView
در لیست موارد خود پیمایش می کند، RecyclerView
از نمونه های View
مواردی که از صفحه اسکرول شده اند مجددا استفاده می کند تا آیتم های جدیدی را هنگام حرکت روی صفحه ایجاد کند. اما تغییرات پیکربندی، مانند چرخش دستگاه، میتواند وضعیت RecyclerView
را بازنشانی کند و کاربران را مجبور کند که دوباره به موقعیت قبلی خود در لیست موارد RecyclerView
حرکت کنند.
RecyclerView
باید وضعیت خود - به ویژه موقعیت اسکرول - و وضعیت عناصر لیست خود را در طول تمام تغییرات پیکربندی حفظ کند.
-
RecyclerView.Adapter#setStateRestorationPolicy()
: مشخص می کند که یکRecyclerView.Adapter
چگونه وضعیت خود را پس از تغییر پیکربندی بازیابی می کند. -
ViewModel
: حالت را برای یک فعالیت یا قطعه نگه می دارد.
سیاست بازیابی حالت RecyclerView.Adapter
را برای ذخیره موقعیت اسکرول RecyclerView
تنظیم کنید. وضعیت موارد لیست RecyclerView
را ذخیره کنید. وضعیت آیتم های لیست را به آداپتور RecyclerView
اضافه کنید و هنگامی که آیتم های لیست به ViewHolder
متصل می شوند وضعیت را بازیابی کنید.
Adapter
را فعال کنید سیاست بازیابی حالت آداپتور RecyclerView
را فعال کنید تا موقعیت پیمایش RecyclerView
در تمام تغییرات پیکربندی حفظ شود. مشخصات خط مشی را به سازنده آداپتور اضافه کنید:
class MyAdapter() : RecyclerView.Adapter<RecyclerView.ViewHolder>() { init { stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY } ... }
class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public Adapter() { setStateRestorationPolicy(StateRestorationPolicy.PREVENT_WHEN_EMPTY); } ... }
وضعیت موارد پیچیده لیست RecyclerView
را ذخیره کنید، مانند مواردی که حاوی عناصر EditText
هستند. به عنوان مثال، برای ذخیره وضعیت یک EditText
، یک پاسخ تماس مشابه با کنترل کننده onClick
اضافه کنید تا تغییرات متن را ثبت کنید. در پاسخ به تماس، تعریف کنید که چه دادههایی ذخیره شوند:
input.addTextChangedListener( afterTextChanged = { text -> text?.let { // Save state here. } } )
input.addTextChangedListener(new TextWatcher() { ... @Override public void afterTextChanged(Editable s) { // Save state here. } });
پاسخ تماس را در Activity
یا Fragment
خود اعلام کنید. از ViewModel
برای ذخیره وضعیت استفاده کنید.
Adapter
اضافه کنید وضعیت موارد لیست را به RecyclerView.Adapter
خود اضافه کنید. هنگامی که Activity
یا Fragment
میزبان شما ایجاد می شود، وضعیت مورد را به سازنده آداپتور منتقل کنید:
val adapter = MyAdapter(items, viewModel.retrieveState())
MyAdapter adapter = new MyAdapter(items, viewModel.retrieveState());
ViewHolder
آداپتور بازیابی کنید در RecyclerView.Adapter
، هنگامی که یک ViewHolder
به یک آیتم متصل می کنید، وضعیت مورد را بازیابی کنید:
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { ... val item = items[position] val state = states.firstOrNull { it.item == item } if (state != null) { holder.restore(state) } }
@Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { ... Item item = items[position]; Arrays.stream(states).filter(state -> state.item == item) .findFirst() .ifPresent(state -> holder.restore(state)); }
RecyclerView
شما اکنون می تواند موقعیت اسکرول خود و وضعیت هر مورد در لیست RecyclerView
را بازیابی کند.
پشتیبانی از صفحه کلیدهای جداشدنی به حداکثر بهره وری کاربر در دستگاه های صفحه نمایش بزرگ کمک می کند. هر بار که صفحهکلید به دستگاهی متصل میشود یا از آن جدا میشود، Android باعث تغییر پیکربندی میشود که میتواند باعث از بین رفتن حالت رابط کاربر شود. برنامه شما میتواند وضعیت خود را ذخیره و بازیابی کند ، به سیستم اجازه میدهد تا فعالیتهای تفریحی را مدیریت کند، یا بازآفرینی فعالیت را برای تغییرات پیکربندی صفحهکلید محدود کند . در همه موارد تمام داده های مربوط به صفحه کلید در یک شیء Configuration
ذخیره می شود. فیلدهای keyboard
و keyboardHidden
شیء پیکربندی حاوی اطلاعاتی در مورد نوع صفحه کلید و در دسترس بودن آن است.
برنامههای بهینهسازی شده برای صفحهنمایشهای بزرگ از هر نوع دستگاه ورودی، از صفحهکلیدهای نرمافزاری و سختافزاری گرفته تا قلم، ماوس، ترکپد و سایر دستگاههای جانبی پشتیبانی میکنند.
پشتیبانی از صفحهکلیدهای خارجی شامل تغییرات پیکربندی است که میتوانید آنها را به دو روش مدیریت کنید:
- به سیستم اجازه دهید فعالیت در حال اجرا را دوباره ایجاد کند و شما مراقب وضعیت برنامه خود باشید.
- تغییر پیکربندی را خودتان مدیریت کنید (فعالیت دوباره ایجاد نخواهد شد):
- تمام مقادیر پیکربندی مرتبط با صفحه کلید را اعلام کنید
- یک کنترل کننده تغییر پیکربندی ایجاد کنید
برنامههای بهرهوری، که اغلب به کنترل دقیق رابط کاربری برای ورود متن و سایر ورودیها نیاز دارند، میتوانند از رویکرد انجام خودت برای مدیریت تغییرات پیکربندی بهره ببرند.
در موارد خاص، ممکن است بخواهید زمانی که صفحه کلید سخت افزاری متصل یا جدا می شود، طرح بندی برنامه خود را تغییر دهید، به عنوان مثال، برای ایجاد فضای بیشتر برای ابزارها یا پنجره های ویرایش.
از آنجایی که تنها راه قابل اعتماد برای گوش دادن به تغییرات پیکربندی، نادیده گرفتن روش onConfigurationChanged()
یک view است، می توانید یک نمونه View جدید به فعالیت برنامه خود اضافه کنید و در کنترلر onConfigurationChanged()
view به تغییرات پیکربندی ناشی از بودن صفحه کلید پاسخ دهید. متصل یا جدا شده
-
android:configChanges
: ویژگی عنصر<activity>
مانیفست برنامه. تغییرات پیکربندی که برنامه مدیریت می کند به سیستم اطلاع می دهد. -
View#onConfigurationChanged()
: روشی که به انتشار یک پیکربندی برنامه جدید واکنش نشان می دهد.
ویژگی configChanges
را اعلام کنید و مقادیر مربوط به صفحه کلید را اضافه کنید. یک View
به سلسله مراتب نمای فعالیت اضافه کنید و به تغییرات پیکربندی گوش دهید.
configChanges
را اعلام کنید با افزودن مقادیر keyboard|keyboardHidden
به لیست تغییرات پیکربندی مدیریت شده قبلی، عنصر <activity>
را در مانیفست برنامه بهروزرسانی کنید:
<activity
…
android:configChanges="...|keyboard|keyboardHidden">
یک نمای جدید اعلام کنید و کد کنترل کننده خود را در متد onConfigurationChanged()
view اضافه کنید:
val v = object : View(this) { override fun onConfigurationChanged(newConfig: Configuration?) { super.onConfigurationChanged(newConfig) // Handler code here. } }
View v = new View(this) { @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Handler code here. } };
اکنون برنامه شما به صفحه کلید خارجی متصل یا جدا شده بدون ایجاد مجدد فعالیت فعلی پاسخ می دهد.
برای یادگیری نحوه ذخیره وضعیت رابط کاربری برنامه خود در طول تغییرات پیکربندی مانند پیوست یا جدا شدن صفحه کلید، به ذخیره حالتهای رابط کاربری مراجعه کنید.
{% کلمه به کلمه %}- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- کنترل تغییرات پیکربندی