عند استهداف الإصدار 35 من حزمة تطوير البرامج (SDK) أو إصدار أحدث على جهاز يعمل بالإصدار 15 من نظام التشغيل Android أو إصدار أحدث، يتم عرض تطبيقك من حافة الشاشة إلى الحافة الأخرى. ويشمل النافذة العرض بالكامل من حيث العرض والارتفاع من خلال الرسم خلف أشرطة النظام. تشمل أشرطة النظام شريط الحالة وشريط الترجمة والشرح وشريط التنقّل.
تحتوي العديد من التطبيقات على شريط تطبيق علوي. يجب أن يمتد شريط التطبيق العلوي إلى الحافة العلوية من الشاشة وأن يظهر خلف شريط الحالة. يمكن اختياريًا تقليل ارتفاع شريط التطبيق العلوي إلى ارتفاع شريط الحالة عند تمرير المحتوى.
تحتوي العديد من التطبيقات أيضًا على شريط تطبيق سفلي أو شريط تنقّل سفلي. يجب أن يمتد هذان الشريطَان أيضًا إلى الحافة السفلية من الشاشة وأن يظهرا خلف شريط التنقّل. وبخلاف ذلك، يجب أن تعرض التطبيقات محتوى قابلاً للتمرير خلف شريط التنقّل.
عند تنفيذ تنسيق "العرض حتى حافة الشاشة" في تطبيقك، ضَع في اعتبارك ما يلي:
- تفعيل ميزة "العرض حتى حافة الشاشة"
- تنفيذ تنسيقات تكيُّفية لتحسين تجربة المستخدم على عوامل الشكل المختلفة
- التعامل مع أي تداخلات مرئية
- عرض الحواجز خلف أشرطة النظام
تفعيل ميزة "العرض حتى حافة الشاشة"
إذا كان تطبيقك يستهدف الإصدار 35 من حزمة تطوير البرامج (SDK) أو إصدارًا أحدث، يتم تفعيل ميزة "العرض حتى حافة الشاشة" تلقائيًا لأجهزة Android 15 أو الإصدارات الأحدث.
لتفعيل ميزة "العرض حتى حافة الشاشة" على إصدارات Android السابقة، استدعِ يدويًا
enableEdgeToEdge في onCreate من Activity.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.enableEdgeToEdge(window)
...
}
Java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WindowCompat.enableEdgeToEdge(getWindow());
...
}
تؤدي الدالة enableEdgeToEdge() تلقائيًا إلى جعل أشرطة النظام شفافة، باستثناء وضع التنقّل باستخدام ثلاثة أزرار حيث يحصل شريط التنقّل على حاجز شفاف. ويتم تعديل ألوان رموز النظام والحاجز استنادًا إلى المظهر الفاتح أو الداكن للنظام.
لتفعيل ميزة "العرض حتى حافة الشاشة" في تطبيقك بدون استخدام الدالة
enableEdgeToEdge()، اطّلِع على
مقالة إعداد ميزة "العرض حتى حافة الشاشة" يدويًا.
التعامل مع التداخلات باستخدام عمليات الإدراج
قد يتم عرض بعض طرق العرض في تطبيقك خلف أشرطة النظام، كما هو موضّح في الشكل 3.
يمكنك معالجة التداخلات من خلال الاستجابة للمساحات الداخلية التي تحدّد الأجزاء من الشاشة التي تتقاطع مع واجهة مستخدِم النظام، مثل شريط التنقّل أو شريط الحالة. قد يعني التقاطع العرض فوق المحتوى، ولكن يمكنه أيضًا إعلام تطبيقك بإيماءات النظام.
أنواع عمليات الإدراج التي تنطبق على عرض تطبيقك من حافة الشاشة إلى الحافة الأخرى هي:
عمليات إدراج أشرطة النظام: هي الأفضل لطرق العرض التي يمكن النقر عليها والتي يجب ألا يتم حجبها مرئيًا بواسطة أشرطة النظام.
مساحات داخلية لصورة مقطوعة للشاشة: للمناطق التي قد يكون فيها صورة مقطوعة للشاشة بسبب شكل الجهاز.
عمليات إدراج إيماءات النظام: هي لمناطق التنقّل بالإيماءات التي يستخدمها النظام والتي لها الأولوية على تطبيقك.
عمليات إدراج أشرطة النظام
عمليات إدراج أشرطة النظام هي النوع الأكثر استخدامًا من عمليات الإدراج. وهي تمثّل المنطقة التي يتم فيها عرض واجهة مستخدم النظام على المحور Z فوق تطبيقك. ويُفضّل استخدامها لنقل طرق العرض أو إضافة مساحة لها في تطبيقك والتي يمكن النقر عليها والتي يجب ألا يتم حجبها مرئيًا بواسطة أشرطة النظام.
على سبيل المثال، يتم حجب زرّ الإجراء الرئيسي (FAB) جزئيًا في الشكل 3 بواسطة شريط التنقّل:
لتجنُّب هذا النوع من التداخل المرئي في وضع الإيماءات أو وضع الأزرار، يمكنك زيادة هوامش طريقة العرض باستخدام
getInsets(int)
مع
WindowInsetsCompat.Type.systemBars().
يوضّح مثال الرمز التالي كيفية تنفيذ عمليات إدراج أشرطة النظام:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) // Apply the insets as a margin to the view. This solution sets // only the bottom, left, and right dimensions, but you can apply whichever // insets are appropriate to your layout. You can also update the view padding // if that's more appropriate. v.updateLayoutParams<MarginLayoutParams> { leftMargin = insets.left bottomMargin = insets.bottom rightMargin = insets.right } // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); // Apply the insets as a margin to the view. This solution sets only the // bottom, left, and right dimensions, but you can apply whichever insets are // appropriate to your layout. You can also update the view padding if that's // more appropriate. MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams(); mlp.leftMargin = insets.left; mlp.bottomMargin = insets.bottom; mlp.rightMargin = insets.right; v.setLayoutParams(mlp); // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. return WindowInsetsCompat.CONSUMED; });
إذا طبّقت هذا الحلّ على المثال الموضّح في الشكل 3، لن ينتج عنه أي تداخل مرئي في وضع الأزرار، كما هو موضّح في الشكل 4:
ينطبق الأمر نفسه على وضع التنقّل بالإيماءات، كما هو موضّح في الشكل 5:
مساحات داخلية للصورة المقطوعة للشاشة
تحتوي بعض الأجهزة على أجزاء مقتطعة من الشاشة. عادةً ما يكون الجزء المقتطع في أعلى الشاشة ومضمّنًا في شريط الحالة. عندما تكون شاشة الجهاز في الوضع الأفقي، قد يكون الجزء المقتطع على الحافة العمودية. استنادًا إلى المحتوى الذي يعرضه تطبيقك على الشاشة، يجب تنفيذ مساحة إضافية لتجنُّب صور مقطوعة للشاشة، لأنّ التطبيقات ستعرض المحتوى تلقائيًا في صورة مقطوعة للشاشة.
على سبيل المثال، تعرض العديد من شاشات التطبيقات قائمة بالعناصر. لا تحجب عناصر القائمة بالجزء المقتطع من الشاشة أو أشرطة النظام.
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets -> val bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() ) v.updatePadding( left = bars.left, top = bars.top, right = bars.right, bottom = bars.bottom, ) WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> { Insets bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() ); v.setPadding(bars.left, bars.top, bars.right, bars.bottom); return WindowInsetsCompat.CONSUMED; });
حدِّد قيمة WindowInsetsCompat من خلال إجراء أو منطقي لأشرطة النظام وأنواع الصورة المقطوعة للشاشة.
اضبط clipToPadding على RecyclerView بحيث يتم تمرير المساحة الإضافية مع عناصر القائمة. يسمح ذلك للعناصر بالظهور خلف أشرطة النظام عندما يمرّر المستخدم الشاشة، كما هو موضّح في المثال التالي.
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
مساحات إدراج إيماءات نظام التشغيل
تمثّل عمليات إدراج إيماءات نظام التشغيل مناطق النافذة التي تكون فيها إيماءات نظام التشغيل لها الأولوية على تطبيقك. وتظهر هذه المناطق باللون البرتقالي في الشكل 6:
على غرار عمليات إدراج أشرطة النظام، يمكنك تجنُّب التداخل مع عمليات إدراج إيماءات نظام التشغيل
باستخدام
getInsets(int)
مع
WindowInsetsCompat.Type.systemGestures().
استخدِم عمليات الإدراج هذه لنقل طرق العرض القابلة للتمرير سريعًا أو إضافة مساحة لها بعيدًا عن الحواف. تشمل حالات الاستخدام الشائعة الأوراق السفلية، والتمرير سريعًا في الألعاب، واللوحات الدائرية التي يتم تنفيذها باستخدامViewPager2.
في الإصدار 10 من نظام التشغيل Android أو الإصدارات الأحدث، تحتوي مساحات الإدراج الخاصة بإيماءات نظام التشغيل على مساحة إدراج سفلية لإيماءة الشاشة الرئيسية، ومساحة إدراج يمنى ويسرى لإيماءات الرجوع:
يوضّح مثال الرمز التالي كيفية تنفيذ عمليات إدراج إيماءات نظام التشغيل:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.updatePadding(insets.left, insets.top, insets.right, insets.bottom) // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()); // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.setPadding(insets.left, insets.top, insets.right, insets.bottom); // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. return WindowInsetsCompat.CONSUMED; });
مكوّنات Material Design
تتعامل العديد من مكوّنات Material Design المستندة إلى طرق العرض في Android
(com.google.android.material) تلقائيًا مع عمليات الإدراج، بما في ذلك
BottomAppBar و
BottomNavigationView و
NavigationRailView
وNavigationView.
ومع ذلك، AppBarLayout
لا تتعامل تلقائيًا مع عمليات الإدراج. أضِف
android:fitsSystemWindows="true"
للتعامل مع عمليات الإدراج العلوية.
تعرَّف على كيفية التعامل مع المساحات الداخلية باستخدام مكوّنات Material Design في Compose.
إرسال عمليات الإدراج المتوافقة مع الأنظمة القديمة
لإيقاف إرسال عمليات الإدراج إلى طرق العرض الفرعية وتجنُّب إضافة مساحة إضافية، يمكنك
استخدام عمليات الإدراج باستخدام الثابت
WindowInsetsCompat.CONSUMED. ومع ذلك، على الأجهزة التي تعمل بالإصدار 10 من نظام التشغيل Android (المستوى 29 لواجهة برمجة التطبيقات والإصدارات الأقدم)، لا يتم إرسال المساحات الداخلية إلى طرق العرض المماثلة بعد استدعاء WindowInsetsCompat.CONSUMED، ما قد يؤدي إلى تداخل مرئي غير مقصود.
للتأكّد من إرسال عمليات الإدراج إلى طرق العرض المماثلة لجميع إصدارات Android
المتوافقة، استخدِم ViewGroupCompat#installCompatInsetsDispatch قبل استخدام
عمليات الإدراج، وهي متاحة على
AndroidX Core وCore-ktx 1.16.0-alpha01
والإصدارات الأحدث.
Kotlin
// Use the i.d. assigned to your layout's root view, e.g. R.id.main val rootView = findViewById(R.id.main) // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView)
Java
// Use the i.d. assigned to your layout's root view, e.g. R.id.main LinearLayout rootView = findViewById(R.id.main); // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView);
الوضع المجسم
يُفضّل عرض بعض المحتوى بملء الشاشة، ما يمنح المستخدم تجربة أكثر جاذبية. يمكنك إخفاء أشرطة النظام في الوضع المجسم باستخدام
مكتبتَي WindowInsetsController
و
WindowInsetsControllerCompat:
Kotlin
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) // Hide the system bars. windowInsetsController.hide(Type.systemBars()) // Show the system bars. windowInsetsController.show(Type.systemBars())
Java
Window window = getWindow(); WindowInsetsControllerCompat windowInsetsController = WindowCompat.getInsetsController(window, window.getDecorView()); if (windowInsetsController == null) { return; } // Hide the system bars. windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); // Show the system bars. windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
يُرجى الرجوع إلى مقالة إخفاء أشرطة النظام في الوضع المجسم لمزيد من المعلومات عن تنفيذ هذه الميزة.
رموز أشرطة النظام
يضمن استدعاء enableEdgeToEdge تعديل ألوان رموز أشرطة النظام عند تغيير مظهر الجهاز.
أثناء استخدام ميزة "العرض حتى حافة الشاشة"، قد تحتاج إلى تعديل ألوان رموز أشرطة النظام يدويًا لتتناسب مع خلفية تطبيقك. على سبيل المثال، لإنشاء رموز فاتحة لشريط الحالة:
Kotlin
WindowCompat.getInsetsController(window, window.decorView) .isAppearanceLightStatusBars = false
Java
WindowCompat.getInsetsController(window, window.getDecorView()) .setAppearanceLightStatusBars(false);
حماية أشرطة النظام
بمجرد أن يستهدف تطبيقك الإصدار 35 من حزمة تطوير البرامج (SDK) أو إصدارًا أحدث، يتم فرض ميزة "العرض حتى حافة الشاشة".
يكون شريط الحالة في النظام وأشرطة التنقّل بالإيماءات شفافة، ولكن شريط التنقّل باستخدام ثلاثة أزرار يكون شفافًا جزئيًا. استدعِ enableEdgeToEdge لجعل هذه الميزة متوافقة مع الأنظمة القديمة.
ومع ذلك، قد لا تعمل الإعدادات التلقائية للنظام في جميع حالات الاستخدام. راجِع إرشادات تصميم أشرطة نظام Android وتصميم ميزة "العرض حتى حافة الشاشة" لتحديد ما إذا كنت تريد استخدام أشرطة نظام شفافة أو شفافة جزئيًا.
إنشاء أشرطة نظام شفافة
أنشئ شريط حالة شفافًا من خلال استهداف الإصدار 15 من نظام التشغيل Android (الإصدار 35 من حزمة تطوير البرامج (SDK)) أو إصدار أحدث أو من خلال استدعاء enableEdgeToEdge() باستخدام الوسيطات التلقائية للإصدارات السابقة.
أنشئ شريط تنقّل شفافًا بالإيماءات من خلال استهداف الإصدار 15 من نظام التشغيل Android أو إصدار أحدث أو من خلال استدعاء enableEdgeToEdge() باستخدام الوسيطات التلقائية للإصدارات السابقة. بالنسبة إلى
شريط التنقّل باستخدام ثلاثة أزرار، اضبط Window.setNavigationBarContrastEnforced
على false وإلا سيتم تطبيق حاجز شفاف جزئيًا.
إنشاء أشرطة نظام شفافة جزئيًا
لإنشاء شريط حالة شفاف جزئيًا، اتّبِع الخطوات التالية:
- حدِّث تبعية
androidx-coreإلى الإصدار 1.16.0-beta01 أو إصدار أحدث - ضَع تنسيق XML في
androidx.core.view.insets.ProtectionLayoutوعيِّن معرّفًا. - يمكنك الوصول إلى
ProtectionLayoutبرمجيًا لضبط عمليات الحماية، مع تحديد الجانب وGradientProtectionلشريط الحالة.
<androidx.core.view.insets.ProtectionLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/list_protection" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView android:id="@+id/item_list" android:clipToPadding="false" android:layout_width="match_parent" android:layout_height="match_parent"> <!--items--> </ScrollView> </androidx.core.view.insets.ProtectionLayout>
findViewById<ProtectionLayout>(R.id.list_protection) .setProtections( listOf( GradientProtection( WindowInsetsCompat.Side.TOP, // Ideally, this is the pane's background color paneBackgroundColor ) ) )
تأكَّد من أنّ ColorInt الذي تم تمريره إلى GradientProtection يطابق خلفية المحتوى. على سبيل المثال، قد يحتوي عرض على شكل قائمة مع تفاصيل معروض على جهاز قابل للطي على GradientProtections مختلفة بألوان مختلفة للوحة القائمة ولوحة التفاصيل.
لا تنشئ شريط التنقّل بالإيماءات الشفاف جزئيًا. لإنشاء شريط تنقّل شفاف جزئيًا باستخدام ثلاثة أزرار، نفِّذ أحد الإجراءَين التاليَين:
- إذا كان التنسيق مضمّنًا في
ProtectionView، يمكنك تمريرColorProtectionأوGradientProtectionإضافية إلى الطريقةsetProtections. قبل إجراء ذلك، تأكَّد من أنّwindow.isNavigationBarContrastEnforced = false. - بخلاف ذلك، اضبط
window.isNavigationBarContrastEnforced = true.
نصائح أخرى
نصائح إضافية عند التعامل مع عمليات الإدراج
عرض المحتوى القابل للتمرير من حافة الشاشة إلى الحافة الأخرى
تأكَّد من أنّ آخر عنصر في القائمة لا يتم حجبها بواسطة أشرطة النظام في RecyclerView أو NestedScrollView من خلال التعامل مع عمليات الإدراج وضبط clipToPadding على false.
يعرض الفيديو التالي RecyclerView مع إيقاف ميزة "العرض حتى حافة الشاشة" (على اليمين) وتفعيلها (على اليسار):
راجِع مقتطفات الرمز في قسم إنشاء قوائم ديناميكية باستخدام RecyclerView للحصول على عينة تعليمات برمجية.
عرض مربّعات الحوار بملء الشاشة من حافة الشاشة إلى الحافة الأخرى
لعرض مربّعات الحوار بملء الشاشة من حافة الشاشة إلى الحافة الأخرى، استدعِ enableEdgeToEdge على مربّع الحوار.
Kotlin
class MyAlertDialogFragment : DialogFragment() {
override fun onStart(){
super.onStart()
dialog?.window?.let { WindowCompat.enableEdgeToEdge(it) }
}
...
}
Java
public class MyAlertDialogFragment extends DialogFragment {
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
Window window = dialog.getWindow();
if (window != null) {
WindowCompat.enableEdgeToEdge(window);
}
}
}
...
}
مراجع إضافية
راجِع المراجع التالية لمزيد من المعلومات عن استخدام ميزة "العرض حتى حافة الشاشة".
المدوّنات
- نصائح للتعامل مع عمليات الإدراج لفرض ميزة "العرض حتى حافة الشاشة" في Android 15
- WindowInsets: أدوات معالجة الأحداث في التنسيقات
التصميم
المستندات الأخرى
الفيديوهات