اندروید تمام مواد لازم را برای برنامه های پنج ستاره با صفحه نمایش بزرگ فراهم می کند. دستور العمل های موجود در این کتاب آشپزی مواد اولیه انتخابی را برای حل مشکلات توسعه خاص انتخاب و ترکیب می کنند. هر دستور غذا شامل بهترین شیوهها، نمونههای کد با کیفیت و دستورالعملهای گام به گام است که به شما کمک میکند تا به یک سرآشپز برتر صفحهنمایش بزرگ تبدیل شوید.
رتبه بندی ستاره ها
دستور العمل ها بر اساس میزان هماهنگی آنها با دستورالعمل های کیفیت برنامه های صفحه نمایش بزرگ رتبه بندی شده است.
![]() | مطابق با معیارهای سطح 1، صفحه نمایش بزرگ متمایز |
![]() | مطابق با معیارهای سطح 2، صفحه نمایش بزرگ بهینه شده است |
![]() | مطابق با معیارهای سطح 3، صفحه نمایش بزرگ آماده است |
![]() | برخی از قابلیتهای صفحه نمایش بزرگ را ارائه میکند، اما از دستورالعملهای کیفیت برنامه صفحه نمایش بزرگ کوتاهی میکند |
![]() | نیازهای یک مورد خاص را برآورده می کند، اما به درستی از صفحه نمایش بزرگ پشتیبانی نمی کند |
پشتیبانی از دوربین Chromebook
در Google Play توسط کاربران Chromebook مورد توجه قرار بگیرید.
اگر برنامه دوربین شما فقط با ویژگیهای اولیه دوربین کار میکند، به فروشگاههای برنامه اجازه ندهید که کاربران Chromebook را از نصب برنامه جلوگیری کنند، فقط به این دلیل که شما سهواً ویژگیهای پیشرفته دوربین موجود در تلفنهای رده بالا را مشخص کردهاید.
کرومبوکها دارای یک دوربین جلو (رو به کاربر) داخلی هستند که برای کنفرانس ویدیویی، عکسهای فوری و سایر برنامهها به خوبی کار میکند. اما همه کرومبوکها دوربین پشتی (جهانی) ندارند و اکثر دوربینهای رو به کاربر در کرومبوکها از فوکوس خودکار یا فلاش پشتیبانی نمیکنند.
بهترین شیوه ها
برنامههای دوربین همه کاره از همه دستگاهها بدون در نظر گرفتن پیکربندی دوربین پشتیبانی میکنند - دستگاههایی با دوربین جلو، دوربین پشت، دوربینهای خارجی متصل به USB.
برای اطمینان از اینکه فروشگاههای برنامهها برنامه شما را برای بیشترین تعداد دستگاه در دسترس قرار میدهند، همیشه همه ویژگیهای دوربین استفاده شده توسط برنامهتان را اعلام کنید و صریحاً مشخص کنید که آیا این ویژگیها مورد نیاز است یا خیر.
مواد تشکیل دهنده
- مجوز
CAMERA
: به برنامه شما امکان دسترسی به دوربین های دستگاه را می دهد - عنصر مانیفست
<uses-feature>
: به فروشگاه های برنامه از ویژگی های استفاده شده توسط برنامه شما اطلاع می دهد - ویژگی
required
: به فروشگاههای برنامه نشان میدهد که آیا برنامه شما میتواند بدون یک ویژگی مشخص کار کند یا خیر
مراحل
خلاصه
مجوز CAMERA
را اعلام کنید. ویژگی های دوربین را که پشتیبانی اولیه دوربین را ارائه می دهند، اعلام کنید. مشخص کنید که آیا هر ویژگی مورد نیاز است یا خیر.
1. مجوز CAMERA
را اعلام کنید
مجوز زیر را به مانیفست برنامه اضافه کنید:
<uses-permission android:name="android.permission.CAMERA" />
2. ویژگی های اصلی دوربین را اعلام کنید
ویژگی های زیر را به مانیفست برنامه اضافه کنید:
<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" />
3. مشخص کنید که آیا هر ویژگی مورد نیاز است یا خیر
android:required="false"
را برای ویژگی android.hardware.camera.any
تنظیم کنید تا دستگاههایی که دارای هر نوع دوربین داخلی یا خارجی هستند یا اصلاً دوربین ندارند، به برنامه شما دسترسی داشته باشند.
برای سایر ویژگیها، android:required="false"
را تنظیم کنید تا مطمئن شوید دستگاههایی مانند Chromebook که دوربین پشتی، فوکوس خودکار یا فلاش ندارند، میتوانند به برنامه شما در فروشگاههای برنامه دسترسی داشته باشند.
نتایج
کاربران Chromebook میتوانند برنامه شما را از Google Play و سایر فروشگاههای برنامه دانلود و نصب کنند. و دستگاههایی که از دوربین با ویژگیهای کامل پشتیبانی میکنند، مانند تلفنها، در عملکرد دوربین خود محدودیتی نخواهند داشت.
با تنظیم صریح ویژگیهای دوربین پشتیبانیشده توسط برنامهتان و مشخص کردن ویژگیهای مورد نیاز برنامه، برنامهتان را تا حد امکان برای دستگاههای زیادی در دسترس قرار دادهاید.
منابع اضافی
برای اطلاعات بیشتر، ویژگی های سخت افزار دوربین را در مستندات <uses-feature>
ببینید.
جهتگیری برنامه در تلفنها محدود شده است، اما در دستگاههای صفحه بزرگ نه
برنامه شما روی تلفنهایی که جهت عمودی هستند عالی کار میکند، بنابراین برنامه را فقط به حالت عمودی محدود کردهاید. اما شما فرصتی برای انجام کارهای بیشتر در صفحه نمایش های بزرگ در جهت افقی می بینید.
چگونه می توانید آن را به هر دو صورت داشته باشید - برنامه را به جهت عمودی در صفحه های کوچک محدود کنید، اما افقی را در صفحه بزرگ فعال کنید؟
بهترین شیوه ها
بهترین برنامه ها به ترجیحات کاربر مانند جهت گیری دستگاه احترام می گذارند.
دستورالعملهای کیفیت برنامه صفحه بزرگ توصیه میکند که برنامهها از همه پیکربندیهای دستگاه، از جمله جهتهای عمودی و افقی، حالت چند پنجرهای، و حالتهای تاشده و بازشده دستگاههای تاشو پشتیبانی کنند. برنامهها باید طرحبندیها و رابطهای کاربری را برای پیکربندیهای مختلف بهینه کنند و برنامهها باید وضعیت را در طول تغییرات پیکربندی ذخیره و بازیابی کنند.
این دستور العمل یک اقدام موقتی است - کمی پشتیبانی از صفحه نمایش بزرگ. از دستور العمل استفاده کنید تا زمانی که بتوانید برنامه خود را بهبود بخشید تا از همه پیکربندیهای دستگاه پشتیبانی کامل کنید.
مواد تشکیل دهنده
-
screenOrientation
: تنظیم مانیفست برنامه که به شما امکان میدهد مشخص کنید برنامه شما چگونه به تغییرات جهتگیری دستگاه پاسخ میدهد. - Jetpack WindowManager : مجموعه ای از کتابخانه ها که به شما امکان می دهد اندازه و نسبت ابعاد پنجره برنامه را تعیین کنید. سازگار با API سطح 14
-
Activity#setRequestedOrientation()
: روشی که با آن می توانید جهت برنامه را در زمان اجرا تغییر دهید
مراحل
خلاصه
برنامه را فعال کنید تا تغییرات جهت را به طور پیش فرض در مانیفست برنامه مدیریت کند. در زمان اجرا، اندازه پنجره برنامه را تعیین کنید. اگر پنجره برنامه کوچک است، جهت گیری برنامه را با لغو تنظیمات جهت مانیفست محدود کنید.
1. تنظیمات جهت را در مانیفست برنامه مشخص کنید
میتوانید از اعلام عنصر screenOrientation
در مانیفست برنامه اجتناب کنید (در این صورت جهتگیری پیشفرض روی unspecified
است) یا جهتگیری صفحه را روی fullUser
تنظیم کنید. اگر کاربر چرخش مبتنی بر حسگر را قفل نکرده باشد، برنامه شما از همه جهتهای دستگاه پشتیبانی میکند.
<activity
android:name=".MyActivity"
android:screenOrientation="fullUser">
تفاوت بین استفاده از unspecified
و fullUser
ظریف اما مهم است. اگر مقدار screenOrientation
را اعلام نکنید، سیستم جهت را انتخاب میکند و خطمشی که سیستم برای تعریف جهت استفاده میکند ممکن است از دستگاهی به دستگاه دیگر متفاوت باشد. از سوی دیگر، مشخص کردن fullUser
با رفتاری که کاربر برای دستگاه تعریف کرده است مطابقت بیشتری دارد: اگر کاربر چرخش مبتنی بر حسگر را قفل کرده باشد، برنامه از اولویت کاربر پیروی می کند. در غیر این صورت، سیستم هر یک از چهار جهت گیری صفحه نمایش (عمودی، منظره، عمودی معکوس، یا منظره معکوس) را اجازه می دهد. android:screenOrientation
ببینید.
2. اندازه صفحه نمایش را تعیین کنید
با تنظیم مانیفست برای پشتیبانی از همه جهتهای مجاز کاربر، میتوانید جهتگیری برنامه را به صورت برنامهنویسی بر اساس اندازه صفحه مشخص کنید.
کتابخانه های 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 مراجعه کنید.
3. تنظیمات مانیفست برنامه را لغو کنید
وقتی تشخیص دادید که دستگاه دارای اندازه صفحه نمایش فشرده است، می توانید 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 صفحه کلید خارجی متوقف و از سر گرفته می شود
بهینهسازی صفحه بزرگ شامل توانایی مدیریت ورودیهای صفحهکلید خارجی، مانند واکنش به فشار دادن Spacebar برای توقف یا ازسرگیری پخش ویدیوها و رسانههای دیگر است. این به ویژه برای تبلتهایی که اغلب به صفحهکلیدهای خارجی متصل میشوند و کرومبوکهایی که معمولاً با صفحهکلیدهای خارجی عرضه میشوند، اما میتوانند در حالت تبلت استفاده شوند، مفید است.
وقتی رسانه تنها عنصر پنجره است (مانند پخش ویدیوی تمام صفحه)، به رویدادهای فشار کلید در سطح فعالیت یا در Jetpack Compose در سطح صفحه پاسخ دهید.
بهترین شیوه ها
هر زمان که برنامه شما یک فایل رسانه ای پخش می کند، کاربران باید بتوانند با فشار دادن Spacebar روی صفحه کلید فیزیکی، پخش را متوقف کرده و از سر بگیرند.
مواد تشکیل دهنده
-
KEYCODE_SPACE
: کد کلید ثابت برای Spacebar.
نوشتن
-
onPreviewKeyEvent
:Modifier
که یک مؤلفه را قادر میسازد تا رویدادهای کلیدی سختافزار را هنگامی که آن (یا یکی از فرزندانش) متمرکز است، رهگیری کند. -
onKeyEvent
: مشابهonPreviewKeyEvent
، اینModifier
یک مؤلفه را قادر میسازد تا رویدادهای کلیدی سختافزار را هنگامی که آن (یا یکی از فرزندانش) متمرکز است، رهگیری کند.
بازدیدها
-
onKeyUp()
: زمانی فراخوانی می شود که یک کلید آزاد می شود و توسط یک view در یک فعالیت کنترل نمی شود.
مراحل
خلاصه
برنامهها و برنامههای مبتنی بر نمایش مبتنی بر Jetpack Compose به فشردن کلیدهای صفحهکلید به روشهای مشابهی پاسخ میدهند: برنامه باید به رویدادهای فشار کلید گوش دهد، رویدادها را فیلتر کند و به فشارهای کلید انتخابشده مانند فشار کلید Spacebar پاسخ دهد.
1. به رویدادهای صفحه کلید گوش دهید
بازدیدها
در یک فعالیت در برنامه خود، روش 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) {
...
}
...
})
2. فشارهای Spacebar را فیلتر کنید
در متد 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
پاسخ دهید.
1. اشیاء رویداد حرکتی را بدست آورید
یک 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. });
2. عمل رویداد و پرچم ها را تعیین کنید
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; });
3. ژست را لغو کنید
وقتی لمس کف دست را تشخیص دادید، میتوانید جلوههای ژست روی صفحه را لغو کنید.
برنامه شما باید تاریخچه ای از اقدامات کاربر داشته باشد تا بتوان ورودی های ناخواسته مانند لمس کف دست را لغو کرد. به عنوان مثال به اجرای یک برنامه طراحی اولیه در تقویت پشتیبانی قلم در یک کد برنامه Android مراجعه کنید.
نتایج
برنامه شما اکنون میتواند لمس کف دست را برای رویدادهای چند اشارهگر در Android 13 و سطوح API بالاتر و رویدادهای تک اشارهای در همه سطوح API شناسایی و رد کند.
منابع اضافی
برای اطلاعات بیشتر به ادامه مطلب مراجعه کنید:
- ویژگیها و APIهای Android 13 - بهبود رد کف دست
- راهنمای توسعه دهندگان
- Codelab - پشتیبانی از قلم را در یک برنامه اندرویدی افزایش دهید
مدیریت حالت WebView
WebView
یک مؤلفه متداول است که یک سیستم پیشرفته برای مدیریت حالت ارائه می دهد. یک WebView
باید وضعیت خود را حفظ کند و موقعیت خود را در سراسر تغییرات پیکربندی حرکت دهد. وقتی کاربر دستگاه را میچرخاند یا یک تلفن تاشو باز میکند، WebView
میتواند موقعیت اسکرول را از دست بدهد، که کاربر را مجبور میکند دوباره از بالای WebView
به موقعیت اسکرول قبلی حرکت کند.
بهترین شیوه ها
تعداد دفعاتی که یک WebView
دوباره ایجاد می شود را به حداقل برسانید. WebView
در مدیریت وضعیت خود خوب است و می توانید با مدیریت هر چه بیشتر تغییرات پیکربندی، از این کیفیت استفاده کنید. برنامه شما باید تغییرات پیکربندی را انجام دهد زیرا Activity
recreation (روش سیستم برای مدیریت تغییرات پیکربندی) WebView
را نیز بازسازی می کند که باعث می شود WebView
حالت خود را از دست بدهد.
مواد تشکیل دهنده
-
android:configChanges
: ویژگی عنصر<activity>
مانیفست. تغییرات پیکربندی انجام شده توسط فعالیت را فهرست می کند. -
View#invalidate()
: روشی که باعث میشود یک view دوباره ترسیم شود. توسطWebView
به ارث رسیده است.
مراحل
خلاصه
برای ذخیره وضعیت WebView
، تا آنجا که ممکن است از بازآفرینی Activity
اجتناب کنید و سپس اجازه دهید WebView
باطل شود تا بتواند با حفظ حالت خود اندازه آن را تغییر دهد.
1. تغییرات پیکربندی را به فایل AndroidManifest.xml
برنامه خود اضافه کنید
با مشخص کردن تغییرات پیکربندی که توسط برنامه شما (به جای سیستم) انجام می شود، از فعالیت تفریحی خودداری کنید:
<activity
android:name=".MyActivity"
android:configChanges="screenLayout|orientation|screenSize
|keyboard|keyboardHidden|smallestScreenSize" />
2. هر زمان که برنامه شما تغییری در پیکربندی دریافت کرد، 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
در لیست موارد خود پیمایش می کند، RecyclerView
از نمونه های View
مواردی که از صفحه اسکرول شده اند مجددا استفاده می کند تا آیتم های جدیدی را هنگام حرکت روی صفحه ایجاد کند. اما تغییرات پیکربندی، مانند چرخش دستگاه، میتواند وضعیت RecyclerView
را بازنشانی کند و کاربران را مجبور کند که دوباره به موقعیت قبلی خود در لیست موارد RecyclerView
حرکت کنند.
بهترین شیوه ها
RecyclerView
باید وضعیت خود - به ویژه موقعیت اسکرول - و وضعیت عناصر لیست خود را در طول تمام تغییرات پیکربندی حفظ کند.
مواد تشکیل دهنده
-
RecyclerView.Adapter#setStateRestorationPolicy()
: مشخص می کند که یکRecyclerView.Adapter
چگونه وضعیت خود را پس از تغییر پیکربندی بازیابی می کند. -
ViewModel
: حالت را برای یک فعالیت یا قطعه نگه می دارد.
مراحل
خلاصه
سیاست بازیابی حالت RecyclerView.Adapter
را برای ذخیره موقعیت اسکرول RecyclerView
تنظیم کنید. وضعیت موارد لیست RecyclerView
را ذخیره کنید. وضعیت موارد لیست را به آداپتور RecyclerView
اضافه کنید و هنگامی که موارد لیست به ViewHolder
متصل می شوند وضعیت را بازیابی کنید.
1. سیاست بازیابی حالت Adapter
را فعال کنید
سیاست بازیابی حالت آداپتور RecyclerView
را فعال کنید تا موقعیت پیمایش RecyclerView
در تمام تغییرات پیکربندی حفظ شود. مشخصات خط مشی را به سازنده آداپتور اضافه کنید:
کاتلین
class MyAdapter() : RecyclerView.Adapter() { init { stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY } ... }
جاوا
class MyAdapter extends RecyclerView.Adapter{ public Adapter() { setStateRestorationPolicy(StateRestorationPolicy.PREVENT_WHEN_EMPTY); } ... }
2. وضعیت آیتم های لیست حالت دار را ذخیره کنید
وضعیت موارد پیچیده لیست 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
برای ذخیره وضعیت استفاده کنید.
3. وضعیت مورد لیست را به Adapter
اضافه کنید
وضعیت موارد لیست را به RecyclerView.Adapter
خود اضافه کنید. هنگامی که Activity
یا Fragment
میزبان شما ایجاد می شود، وضعیت مورد را به سازنده آداپتور منتقل کنید:
کاتلین
val adapter = MyAdapter(items, viewModel.retrieveState())
جاوا
MyAdapter adapter = new MyAdapter(items, viewModel.retrieveState());
4. وضعیت مورد لیست را در 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
به سلسله مراتب نمای فعالیت اضافه کنید و به تغییرات پیکربندی گوش دهید.
1. ویژگی configChanges
را اعلام کنید
با افزودن مقادیر keyboard|keyboardHidden
به لیست تغییرات پیکربندی مدیریت شده قبلی، عنصر <activity>
را در مانیفست برنامه بهروزرسانی کنید:
<activity
…
android:configChanges="...|keyboard|keyboardHidden">
2. یک نمای خالی به سلسله مراتب view اضافه کنید
یک نمای جدید اعلام کنید و کد کنترل کننده خود را در متد 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. } };
نتایج
اکنون برنامه شما به صفحه کلید خارجی متصل یا جدا شده بدون ایجاد مجدد فعالیت فعلی پاسخ می دهد.
منابع اضافی
برای یادگیری نحوه ذخیره وضعیت رابط کاربری برنامه خود در طول تغییرات پیکربندی مانند پیوست یا جدا شدن صفحه کلید، به ذخیره حالتهای رابط کاربری مراجعه کنید.
{% کلمه به کلمه %}برای شما توصیه می شود
- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- کنترل تغییرات پیکربندی