يعمل تطبيقك بشكلٍ رائع على الهواتف في الوضع العمودي، لذا اخترت تقييد التطبيق بالوضع العمودي فقط. ولكن يمكنك إجراء المزيد من الإجراءات على الشاشات الكبيرة في الوضع المُسطّح.
كيف يمكنك استخدام التطبيق بالاتجاهين، أي تقييد التطبيق بالاتجاه العمودي على الشاشات الصغيرة، ولكن تفعيل الاتجاه الأفقي على الشاشات الكبيرة؟
هذا الدليل هو إجراء مؤقت إلى أن تتمكّن من تحسين تطبيقك لتوفير دعم كامل لجميع إعدادات الأجهزة.
إدارة اتجاه التطبيق
لتفعيل الوضع الأفقي على الشاشات الكبيرة، اضبط بيان تطبيقك لمعالجة تغييرات الاتجاه تلقائيًا. في وقت التشغيل، حدِّد حجم نافذة التطبيق. إذا كانت نافذة التطبيق صغيرة، يمكنك تقييد اتجاه التطبيق من خلال إلغاء إعداد اتجاه البيان.
1. تحديد إعداد الاتجاه في بيان التطبيق
يمكنك إما تجنُّب الإفصاح عن عنصر screenOrientation
في بيان
التطبيق (وفي هذه الحالة يكون الاتجاه التلقائي هو unspecified
) أو ضبط اتجاه
الشاشة على fullUser
. إذا لم يحظر المستخدم التدوير المستنِد إلى أداة الاستشعار،
سيتوافق تطبيقك مع جميع أوضاع الجهاز.
<activity
android:name=".MyActivity"
android:screenOrientation="fullUser">
الفرق بين unspecified
وfullUser
بسيط ولكنه مهم. إذا
لم تحدّد قيمة screenOrientation
، سيختار النظام
اتجاه العرض، وقد تختلف السياسة التي يستخدمها النظام لتحديد الاتجاه
من جهاز إلى آخر. من ناحية أخرى، يتوافق تحديد fullUser
بشكلٍ أوثق مع السلوك الذي حدّده المستخدم للجهاز: إذا كان المستخدم قد
قفل التدوير المستنِد إلى أجهزة الاستشعار، سيتّبع التطبيق الإعدادات المفضّلة للمستخدم، وإلا،
سيسمح النظام بأي من الاتجاهات الأربعة المحتملة للشاشة (عمودي أو
أفقي أو عمودي معكوس أو أفقي معكوس). يُرجى الاطّلاع على screenOrientation
.
2- تحديد حجم الشاشة
عند ضبط البيان لتتوافق مع جميع الاتجاهات المسموح بها للمستخدم، يمكنك تحديد اتجاه التطبيق آليًا استنادًا إلى حجم الشاشة.
أضِف مكتبات Jetpack WindowManager إلى ملف build.gradle
أوملف
build.gradle.kts
الخاص بالوحدة:
Kotlin
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
لتحديد حجم الشاشة:
Kotlin
/** 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 }
Java
/** 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()
لأنّه يمكن تشغيل التطبيق في وضع "نوافذ متعدّدة"، ما يؤدي إلى تجاهل إعداد اتجاه الشاشة. ما مِن فائدة من تحديد حجم نافذة التطبيق وإلغاء إعداد الاتجاه ما لم تكن نافذة التطبيق هي شاشة الجهاز بالكامل.
اطّلِع على WindowManager للحصول على تعليمات حول إدراج التبعيات لإتاحة الأسلوب
computeMaximumWindowMetrics()
في تطبيقك.
3- إلغاء إعداد بيان التطبيق
بعد تحديد أنّ حجم شاشة الجهاز صغير، يمكنك استدعاء
Activity#setRequestedOrientation()
لإلغاء إعداد
screenOrientation
في البيان:
Kotlin
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 } }) }
Java
@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()
، يمكنك الحصول على الحد الأقصى لمقاييس النافذة وإلغاء إعدادات
الاتجاه كلما تم تغيير حجم النشاط أو نقله بين الشاشات،
مثلاً بعد تدوير الجهاز أو عند طي جهاز قابل للطي أو فتحه.
لمزيد من المعلومات حول حالات حدوث تغييرات الإعدادات وحالات تسببها في
إعادة إنشاء النشاط، يُرجى الاطّلاع على مقالة معالجة تغييرات الإعدادات.
النقاط الرئيسية
screenOrientation
: إعداد بيان التطبيق الذي يتيح لك تحديد كيفية استجابة تطبيقك لتغييرات وضع الجهاز- Jetpack WindowManager: مجموعة من المكتبات التي تتيح لك تحديد حجم نافذة التطبيق ونسبتها العرضية إلى الارتفاع، وهي متوافقة مع الإصدارات الأقدم حتى المستوى 14 من واجهة برمجة التطبيقات
Activity#setRequestedOrientation()
: الطريقة التي يمكنك من خلالها تغيير اتجاه التطبيق أثناء التشغيل
النتائج
من المفترض أن يظل تطبيقك في الوضع العمودي على الشاشات الصغيرة بغض النظر عن تدوير الجهاز. على الشاشات الكبيرة، يجب أن يكون التطبيق متوافقًا مع الاتجاهَين الأفقي وال عمودي.
المجموعات التي تتضمّن هذا الدليل
هذا الدليل هو جزء من مجموعات "الأدلة السريعة" المنظَّمة التي تتناول أهدافًا أوسع في تطوير تطبيقات Android:
![](https://developer.android.com/static/images/quick-guides/collection-illustration.png?hl=ar)