عرض المحتوى بشكل شامل في تطبيقك

تجربة ميزة "الكتابة"
‫Jetpack Compose هي مجموعة أدوات واجهة المستخدم المُقترَحة لنظام التشغيل Android. تعرَّف على كيفية العمل على ملء الشاشة في ميزة "الإنشاء".

بعد استهداف الإصدار 35 من حزمة تطوير البرامج (SDK) أو إصدار أحدث على جهاز يعمل بالإصدار 15 من نظام التشغيل Android أو إصدار أحدث، سيتم عرض تطبيقك على الشاشة بالكامل. تمتد النافذة على العرض والارتفاع بالكامل للشاشة من خلال الرسم خلف أشرطة النظام. تشمل أشرطة النظام شريط الحالة وشريط الترجمة والشرح وشريط التنقّل.

تحتوي العديد من التطبيقات على شريط تطبيق في أعلى الشاشة. يجب أن يصل شريط التطبيق العلوي إلى الحافة العلوية من الشاشة وأن يظهر خلف شريط الحالة. يمكنك اختياريًا تصغير شريط التطبيق العلوي ليصبح بارتفاع شريط الحالة عند الانتقال للأسفل أو للأعلى في المحتوى.

تتضمّن العديد من التطبيقات أيضًا شريط تطبيق سفلي أو شريط تنقّل سفلي. يجب أن تمتد هذه الأشرطة أيضًا إلى الحافة السفلية من الشاشة وأن تظهر خلف شريط التنقّل. بخلاف ذلك، يجب أن تعرض التطبيقات محتوى قابلاً للتقديم أو الإيقاف خلف شريط التنقّل.

الشكل 1. أشرطة النظام بتنسيق من الحافة إلى الحافة

عند تنفيذ تنسيق من الحافة إلى الحافة في تطبيقك، يُرجى مراعاة ما يلي:

  1. تفعيل ميزة "العرض حتى حافة الشاشة"
  2. عالج أيّ تداخلات مرئية.
  3. ننصحك بعرض الشاشات المصغّرة خلف أشرطة النظام.
مثال على صور خلف شريط الحالة
الشكل 2. مثال على الصور التي تظهر في خلفية شريط الحالة

تفعيل ميزة "العرض حتى حافة الشاشة"

إذا كان تطبيقك يستهدف الإصدار 35 من حزمة تطوير البرامج (SDK) أو إصدارًا أحدث، يتم تفعيل ميزة "العرض حتى حافة الشاشة" تلقائيًا على أجهزة Android 15 أو الإصدارات الأحدث.

لتفعيل ميزة "العرض حتى حافة الشاشة" على إصدارات Android السابقة، اتّبِع الخطوات التالية:

  1. أضِف تبعية لمكتبة androidx.activity في ملف build.gradle الخاص بتطبيقك أو وحدتك:

    Kotlin

    dependencies {
        val activity_version = activity_version
        // Java language implementation
        implementation("androidx.activity:activity:$activity_version")
        // Kotlin
        implementation("androidx.activity:activity-ktx:$activity_version")
    }
    

    رائع

    dependencies {
        def activity_version = activity_version
        // Java language implementation
        implementation 'androidx.activity:activity:$activity_version'
        // Kotlin
        implementation 'androidx.activity:activity-ktx:$activity_version'
    }
    
  2. استورِد دالة الإضافة enableEdgeToEdge إلى تطبيقك:

يمكنك تفعيل ميزة "العرض حتى حافة الشاشة" يدويًا من خلال الاتصال برقم enableEdgeToEdge في onCreate من Activity. يجب استدعاؤه قبل setContentView.

Kotlin

     override fun onCreate(savedInstanceState: Bundle?) {
       enableEdgeToEdge()
       super.onCreate(savedInstanceState)
       ...
     }
   

Java

     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
       EdgeToEdge.enable(this);
       super.onCreate(savedInstanceState);
       ...
     }
   

بشكلٍ تلقائي، يجعل enableEdgeToEdge() أشرطة النظام شفافة، باستثناء وضع التنقّل باستخدام 3 أزرار الذي يحصل فيه شريط الحالة على حاجب شفاف. يتم تعديل ألوان رموز النظام والشاشة البينية استنادًا إلى المظهر الفاتح أو الداكن للنظام.

تُعلن دالة enableEdgeToEdge() تلقائيًا أنّه يجب أن يتم عرض التطبيق من الحافة إلى الحافة، كما تضبط ألوان أشرطة النظام.

لتفعيل ميزة "العرض حتى حافة الشاشة" في تطبيقك بدون استخدام الدالة enableEdgeToEdge()، اطّلِع على مقالة إعداد ميزة "العرض حتى حافة الشاشة" يدويًا.

التعامل مع التداخلات باستخدام الأجزاء المضمّنة

قد يتم عرض بعض طرق عرض تطبيقك خلف أشرطة النظام، كما هو موضّح في الشكل 3.

يمكنك معالجة التداخلات من خلال التفاعل مع الأجزاء المضمّنة التي تحدّد أجزاء الشاشة التي تتداخل مع واجهة مستخدم النظام، مثل شريط التنقّل أو شريط الحالة. يمكن أن تعني التداخل العرض فوق المحتوى، ولكن يمكن أن يُعلم ذلك تطبيقك أيضًا بإيماءات النظام.

في ما يلي أنواع الأجزاء المضمّنة التي تنطبق على عرض تطبيقك من الحافة إلى الحافة:

  • أشرطة النظام المضمّنة: وهي الأنسب للعروض التي يمكن النقر عليها والتي يجب ألا تُحجب بصرياً من خلال أشرطة النظام.

  • Display cutout insets (أجزاء الشاشة المقطوعة): للمناطق التي قد تتضمّن جزءًا مقطوعًا من الشاشة بسبب شكل الجهاز

  • أجزاء الإيماءات في النظام: لمناطق التنقّل بالإيماءات التي يستخدمها النظام والتي تحظى بالأولوية على تطبيقك.

أقسام شريط النظام

إنّ مربّعات الادراج في شريط النظام هي أكثر أنواع مربّعات الادراج استخدامًا. وهي تمثّل المنطقة التي يتم فيها عرض واجهة مستخدم النظام في محور Z فوق تطبيقك. وأفضل استخدام لها هو نقل أو إضافة مساحة إلى طرق العرض في تطبيقك التي يمكن النقر عليها والتي يجب ألا يتم حجبها بصريًا من خلال أشرطة النظام.

على سبيل المثال، زر الإجراء العائم (FAB) في الشكل 3 مُخفَّى جزئيًا من خلال شريط التنقّل:

مثال على شاشة ملء الشاشة تم تنفيذها، ولكن شريط التنقّل يغطي التطبيق المصغّر للإجراءات السريعة
الشكل 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 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 want the window insets to keep passing
  // down to descendant views.
    return WindowInsetsCompat.CONSUMED;
});

في حال تطبيق هذا الحلّ على المثال المعروض في الشكل 3، لن يؤدي ذلك إلى تداخل مرئي في وضع الزر، كما هو موضّح في الشكل 4:

شريط تنقّل شفاف لا يغطي زر الإجراء الرئيسي
الشكل 4. حلّ مشكلة التداخل المرئي في وضع "الأزرار"

وينطبق الأمر نفسه على وضع التنقّل بالإيماءات، كما هو موضّح في الشكل 5:

من الحافة إلى الحافة مع التنقّل بالإيماءات
الشكل 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:

مثال على أماكن إدراج إيماءات النظام
الشكل 6. أجزاء الإيماءات في النظام

مثل الأجزاء المُدمَجة في شريط النظام، يمكنك تجنُّب تداخل الأجزاء المُدمَجة في إيماءات النظام باستخدام getInsets(int) مع WindowInsetsCompat.Type.systemGestures().

استخدِم هذه الأجزاء المُدمجة لنقل العروض التي يمكن التمرير عليها أو إبعادها عن الحواف. تشمل حالات الاستخدام الشائعة الأوراق السفلية، والتمرير السريع في الألعاب، وعروض الصور الدوّارة التي يتم تنفيذها باستخدام ViewPager2.

في نظام التشغيل Android 10 أو الإصدارات الأحدث، تحتوي عناصر الإيماءات المضمّنة للنظام على عنصر مضمّن في أسفل الشاشة لإيماءة الرجوع إلى الصفحة الرئيسية، وعنصر مضمّن على يمين الشاشة وعلى يسارها لإيماءات الرجوع:

مثال على قياسات الإيماءات المضمّنة في النظام
الشكل 7. قياسات موضع إيماءات النظام

يوضّح مثال الرمز البرمجي التالي كيفية تنفيذ المكوّنات المضمّنة لإيماءات النظام:

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

تتعامل العديد من مكوّنات Android Material (com.google.android.material){:.external} المستندة إلى المشاهد تلقائيًا مع الأجزاء المضمّنة، بما في ذلك BottomAppBar، BottomNavigationView، NavigationRailView وNavigationView.

ومع ذلك، لا يعالج AppBarLayout العناصر المضمّنة تلقائيًا. أضِف android:fitsSystemWindows="true" لمعالجة العناصر المضمّنة في أعلى الصفحة.

اطّلِع على كيفية التعامل مع الأجزاء المُدمجة باستخدام مكونات Material في أداة Compose.

وضع مجسم

يُفضَّل مشاهدة بعض المحتوى في وضع ملء الشاشة، ما يمنح المستخدم تجربة أكثر إحاطةً. يمكنك إخفاء أشرطة النظام والوضع الشامل باستخدام مكتبتَي 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());

يُرجى الاطّلاع على المقالة إخفاء أشرطة النظام في الوضع الشامل لمزيد من المعلومات حول تنفيذ هذه الميزة.

حماية شريط النظام

بعد أن يستهدف تطبيقك الإصدار 35 من حزمة تطوير البرامج (SDK) أو إصدارًا أحدث، يتم فرض العرض حتى حافة الشاشة. يكون شريط حالة النظام وأشرطة التنقّل بالإيماءات شفافين، ولكن يكون شريط التنقّل بثلاثة أزرار شفافًا.

لإزالة الحماية التلقائية الشفافة لخلفية شريط التنقّل المكوّن من ثلاثة أزرار، اضبط Window.setNavigationBarContrastEnforced على false.

مصادر إضافية

اطّلِع على المراجع التالية للحصول على مزيد من المعلومات عن WindowInsets واستخدام الحركات للتنقّل وطريقة عمل الأجزاء المضمّنة: