إدراجات النوافذ في "إنشاء"

يكون نظام Android الأساسي مسؤولاً عن رسم واجهة مستخدم النظام، مثل شريط الحالة وشريط التنقل. يتم عرض واجهة مستخدم النظام هذه بغض النظر عن التطبيق الذي يستخدمه المستخدم. توفّر WindowInsets معلومات عن واجهة مستخدم النظام للتأكّد من أنّ تطبيقك يعرض المنطقة الصحيحة ومن أنّ واجهة مستخدم النظام لا تحجب واجهة المستخدم.

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

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

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

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

الاطّلاع على الأساسيات المُدرجة

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

يتم تحديد حجم واجهة مستخدم النظام والمعلومات حول مكان وضعها عبر المجموعات.

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

تتوفّر هذه الأنواع المدمَجة من الأجهزة في Android من خلال WindowInsets:

WindowInsets.statusBars

التفاصيل الداخلية تصف أشرطة الحالة. هذه هي أشرطة واجهة المستخدم في النظام التي تحتوي على رموز الإشعارات ومؤشرات أخرى.

WindowInsets.statusBarsIgnoringVisibility

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

WindowInsets.navigationBars

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

WindowInsets.navigationBarsIgnoringVisibility

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

WindowInsets.captionBar

المساحة الداخلية تصف ديكور نافذة واجهة مستخدم النظام إذا كانت في نافذة حرة، مثل شريط العنوان العلوي.

WindowInsets.captionBarIgnoringVisibility

يتم إدراج جزء داخلي في شريط الترجمة عندما تكون مرئية. إذا كانت أشرطة الترجمة مخفية حاليًا، فستكون الأجزاء الداخلية في شريط الترجمة والشرح فارغة، ولكن لن تكون هذه الأجزاء الداخلية فارغة.

WindowInsets.systemBars

اتحاد عناصر شريط النظام الداخلية، والتي تشمل أشرطة الحالة وأشرطة التنقل وشريط الترجمة

WindowInsets.systemBarsIgnoringVisibility

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

WindowInsets.ime

تصف المساحات الداخلية مقدار المساحة في الأسفل التي تشغلها لوحة مفاتيح البرنامج.

WindowInsets.imeAnimationSource

تصف المساحات الداخلية مقدار المساحة التي شغلتها لوحة المفاتيح البرمجية قبل الحركة الحالية للوحة المفاتيح.

WindowInsets.imeAnimationTarget

تصف المساحات الداخلية مقدار المساحة التي ستشغلها لوحة المفاتيح البرمجية بعد الحركة الحالية للوحة المفاتيح.

WindowInsets.tappableElement

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

WindowInsets.tappableElementIgnoringVisibility

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

WindowInsets.systemGestures

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

WindowInsets.mandatorySystemGestures

مجموعة فرعية من إيماءات النظام التي سيعالجها النظام دائمًا، ولا يمكن إيقافها من خلال Modifier.systemGestureExclusion.

WindowInsets.displayCutout

الأجزاء الداخلية التي تمثّل مقدار التباعد المطلوب لتجنّب التداخل مع الصورة المقطوعة للشاشة (الثقب أو الثقب الصغير).

WindowInsets.waterfall

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

ويتم تلخيص هذه الأنواع من خلال ثلاثة أنواع داخلية "آمنة" تضمن عدم حجب المحتوى:

تعمل أنواع الأجزاء الداخلية "الآمنة" هذه على حماية المحتوى بطرق مختلفة، استنادًا إلى الأجزاء الأساسية من النظام الأساسي:

  • استخدِم WindowInsets.safeDrawing لحماية المحتوى الذي لا يجب وضعه أسفل أي واجهة من واجهات مستخدم النظام. وهذا هو الاستخدام الأكثر شيوعًا للمساحات الداخلية وذلك لمنع رسم محتوى تحجبه واجهة مستخدم النظام (إما جزئيًا أو كليًا).
  • يمكنك استخدام WindowInsets.safeGestures لحماية المحتوى باستخدام الإيماءات. يتجنّب ذلك تضارب إيماءات النظام مع إيماءات التطبيق (مثل إيماءات البطاقات السفلية أو لوحات العرض الدوّارة أو الألعاب).
  • يمكنك استخدام WindowInsets.safeContent كمزيج من WindowInsets.safeDrawing وWindowInsets.safeGestures لضمان أنّ المحتوى لا يتداخل بشكل مرئي ومن أنّ الإيماءات لا تتداخل.

إعداد مجموعات داخلية

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

  1. يمكنك الاتصال بالرقم enableEdgeToEdge() في Activity.onCreate. ويطلب هذا الاستدعاء أن يعرضه تطبيقك خلف واجهة مستخدم النظام. سيتحكّم تطبيقك بعد ذلك في كيفية استخدام هذه المساحات الداخلية لضبط واجهة المستخدم.
  2. يمكنك ضبط "android:windowSoftInputMode="adjustResize"" في حقل "AndroidManifest.xml" الخاص بنشاطك. يسمح هذا الإعداد لتطبيقك بتلقي حجم أداة IME للبرنامج على شكل مجموعات داخلية، والتي يمكنك استخدامها لوضع المحتوى وتصميمه بشكل مناسب عند ظهور أداة IME واختفائها في التطبيق.

    <!-- in your AndroidManifest.xml file: -->
    <activity
      android:name=".ui.MainActivity"
      android:label="@string/app_name"
      android:windowSoftInputMode="adjustResize"
      android:theme="@style/Theme.MyApplication"
      android:exported="true">
    

إنشاء واجهات برمجة التطبيقات

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

على سبيل المثال، هذه هي الطريقة الأساسية لتطبيق التفاصيل الداخلية على محتوى تطبيقك بالكامل:

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

    enableEdgeToEdge()

    setContent {
        Box(Modifier.safeDrawingPadding()) {
            // the rest of the app
        }
    }
}

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

تتم إضافة رسوم متحركة إلى كل أنواع المساحات الداخلية هذه تلقائيًا باستخدام الصور المتحركة لأداة IME التي يتم نقلها إلى الإصدار 21 من واجهة برمجة التطبيقات. بالإضافة إلى ذلك، يتم أيضًا تحريك جميع التخطيطات التي تستخدم هذه المجموعات الداخلية تلقائيًا مع تغيير القيم الداخلية.

هناك طريقتان أساسيتان لاستخدام أنواع إدراج الإعلانات هذه لضبط التنسيقات القابلة للإنشاء: مفاتيح تعديل المساحة المتروكة ومفاتيح تعديل الحجم الداخلي.

معدِّلات المساحة المتروكة

يطبِّق Modifier.windowInsetsPadding(windowInsets: WindowInsets) المساحات الداخلية المحدّدة للنافذة كمساحة متروكة، وهي تعمل تمامًا على النحو المعتاد في Modifier.padding. على سبيل المثال، يطبّق Modifier.windowInsetsPadding(WindowInsets.safeDrawing) المساحات الداخلية للرسم الآمن كمساحة متروكة على الجوانب الأربعة.

هناك أيضًا العديد من طرق المرافق المدمجة لأنواع إدراج الإعلانات الأكثر شيوعًا. Modifier.safeDrawingPadding() هي إحدى الطرق، بما يعادل Modifier.windowInsetsPadding(WindowInsets.safeDrawing). هناك تعديلات مماثلة لأنواع الإدخالات الأخرى.

معدِّلات حجم لوحة البيانات الداخلية

تعمل مفاتيح التعديل التالية على تطبيق مقدار داخليات النوافذ من خلال تعيين حجم المكوِّن ليكون حجم المجموعات الداخلية:

Modifier.windowInsetsStartWidth(windowInsets: WindowInsets)

يتيح هذا الخيار تطبيق جانب البداية لـ windowInsets كعرض (مثل Modifier.width).

Modifier.windowInsetsEndWidth(windowInsets: WindowInsets)

يتم تطبيق جانب نهاية إضافات النافذة كعرض (مثل Modifier.width).

Modifier.windowInsetsTopHeight(windowInsets: WindowInsets)

يتم تطبيق الجانب العلوي من إضافات النافذة كارتفاع (مثل Modifier.height).

Modifier.windowInsetsBottomHeight(windowInsets: WindowInsets)

يتم تطبيق الجانب السفلي من "إعدادات النافذة" كارتفاع (مثل Modifier.height).

هذه مفاتيح التعديل مفيدة بشكل خاص عند تغيير حجم Spacer الذي يشغل مساحة الأجزاء الداخلية:

LazyColumn(
    Modifier.imePadding()
) {
    // Other content
    item {
        Spacer(
            Modifier.windowInsetsBottomHeight(
                WindowInsets.systemBars
            )
        )
    }
}

استهلاك مساحة التخزين الداخلية

إنّ مفاتيح تعديل المساحة المتروكة (windowInsetsPadding والمساعدات مثل safeDrawingPadding) تستهلك تلقائيًا جزءًا من المساحات الداخلية التي يتم تطبيقها كمساحة متروكة. عند التعمّق أكثر في شجرة التركيب، تدرك أنّ مفاتيح تعديل المساحة المتروكة الداخلية المضمّنة ومفاتيح تعديل الحجم الداخلي قد استهلكت جزءًا من المجموعات من قبل من خلال تعديلات المساحة المتروكة الخارجية، وتجنَّب استخدام الجزء نفسه من الإعلانات الداخلية أكثر من مرة، ما قد ينتج عنه مساحة إضافية كبيرة جدًا.

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

ونتيجةً لذلك، تعمل تعديلات المساحة المتروكة المتداخلة تلقائيًا على تغيير مقدار المساحة المتروكة المطبقة على كل عنصر قابل للإنشاء.

وبالنظر إلى مثال LazyColumn نفسه كما في السابق، يتم تغيير حجم LazyColumn باستخدام مفتاح التعديل imePadding. داخل LazyColumn، يكون حجم العنصر الأخير هو ارتفاع الجزء السفلي من أشرطة النظام:

LazyColumn(
    Modifier.imePadding()
) {
    // Other content
    item {
        Spacer(
            Modifier.windowInsetsBottomHeight(
                WindowInsets.systemBars
            )
        )
    }
}

عند إغلاق أداة تحرير أسلوب الإدخال (IME)، لا يطبق مفتاح التعديل imePadding() أي مساحة متروكة، حيث لا يكون هناك ارتفاع في أداة IME. بما أنّ مُعدِّل imePadding() لا يستخدم مساحة متروكة، لن يتم استهلاك أي مساحات داخلية، وسيكون ارتفاع Spacer مطابقًا لحجم الجانب السفلي من أشرطة النظام.

عند فتح أداة IME، يتم تشغيل رسم متحرك يُطابق حجم أداة IME ، ويبدأ مفتاح التعديل imePadding() في تطبيق المساحة المتروكة السفلية لتغيير حجم LazyColumn عند فتح أداة IME. عندما يبدأ مفتاح التعديل imePadding() في تطبيق المساحة المتروكة السفلية، يبدأ أيضًا في استهلاك هذا القدر من الأجزاء الداخلية. وبالتالي، يبدأ ارتفاع Spacer في الانخفاض، إذ سبق أن تم تطبيق مسافات بين أشرطة النظام من خلال مفتاح التعديل imePadding(). بعد أن يطبّق أداة التعديل imePadding() مقدارًا من المساحة المتروكة السفلية أكبر من أشرطة النظام، يصبح ارتفاع Spacer صفرًا.

عند إغلاق أداة IME، تحدث التغييرات بشكل عكسي: يبدأ Spacer في التوسع من ارتفاع صفر بعد تطبيق imePadding() بحجم أقل من الجانب السفلي من أشرطة النظام، إلى أن يتطابق Spacer في النهاية مع ارتفاع الجانب السفلي من أشرطة النظام بعد تحريك أداة IME بالكامل.

الشكل 2. عمود الكسول بين الحافتين مع TextField

ويحدث ذلك من خلال التواصل بين جميع معدِّلات windowInsetsPadding، ويمكن أن يتأثر بطريقتين أخريَين.

يستهلك Modifier.consumeWindowInsets(insets: WindowInsets) أيضًا إدراجات داخلية تمامًا مثل Modifier.windowInsetsPadding، ولكنه لا يطبِّق الأجزاء الداخلية المستهلكة كمساحة متروكة. ويكون هذا مفيدًا عند استخدام معدِّلات الحجم الداخلي للإشارة إلى الأشقاء أنّه قد تم استهلاك كمية معيّنة من الأجزاء الداخلية:

Column(Modifier.verticalScroll(rememberScrollState())) {
    Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars))

    Column(
        Modifier.consumeWindowInsets(
            WindowInsets.systemBars.only(WindowInsetsSides.Vertical)
        )
    ) {
        // content
        Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
    }

    Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars))
}

يعمل Modifier.consumeWindowInsets(paddingValues: PaddingValues) بشكل مشابه جدًا للإصدار الذي يتضمن الوسيطة WindowInsets، ولكنه يتخذ استخدام PaddingValues عشوائيًا. يفيد ذلك في إعلام الأطفال عندما يتم توفير مساحة متروكة أو مسافات من خلال آلية أخرى غير مفاتيح تعديل المساحة المتروكة، مثل علامة Modifier.padding عادية أو فواصل ذات ارتفاع ثابت:

@OptIn(ExperimentalLayoutApi::class)
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) {
    // content
    Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
}

في الحالات التي تحتاج فيها إلى ظهور نوافذ داخلية غير قابلة للاستهلاك بدون استهلاك، استخدِم قيم WindowInsets مباشرةً أو استخدِم WindowInsets.asPaddingValues() لعرض PaddingValues من المساحات الداخلية التي لا تتأثر بالاستهلاك. ومع ذلك، ونظرًا للتنبيهات الواردة أدناه، ننصحك باستخدام معدِّلات مساحة التخزين الداخلية للنوافذ ومعدِّلات حجم المساحة الداخلية للنوافذ كلما أمكن ذلك.

مرحلتَي Insets وJetpack Compose

يستخدم Compose واجهات برمجة التطبيقات الأساسية في AndroidX لتحديث الأقسام الداخلية وتحريكها، والتي تستخدم واجهات برمجة تطبيقات النظام الأساسي الأساسية التي تدير الوحدات الداخلية. وبسبب سلوك هذه المنصة، ترتبط المساحات الداخلية بعلاقة خاصة مع مراحل Jetpack Compose.

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

صور متحركة لأداة IME في لوحة المفاتيح مع WindowInsets

يمكنك تطبيق Modifier.imeNestedScroll() على حاوية تمرير لفتح أداة IME وإغلاقها تلقائيًا عند الانتقال إلى أسفل الحاوية.

class WindowInsetsExampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        WindowCompat.setDecorFitsSystemWindows(window, false)

        setContent {
            MaterialTheme {
                MyScreen()
            }
        }
    }
}

@OptIn(ExperimentalLayoutApi::class)
@Composable
fun MyScreen() {
    Box {
        LazyColumn(
            modifier = Modifier
                .fillMaxSize() // fill the entire window
                .imePadding() // padding for the bottom for the IME
                .imeNestedScroll(), // scroll IME at the bottom
            content = { }
        )
        FloatingActionButton(
            modifier = Modifier
                .align(Alignment.BottomEnd)
                .padding(16.dp) // normal 16dp of padding for FABs
                .navigationBarsPadding() // padding for navigation bar
                .imePadding(), // padding for when IME appears
            onClick = { }
        ) {
            Icon(imageVector = Icons.Filled.Add, contentDescription = "Add")
        }
    }
}

صورة متحركة تعرض عنصرًا في واجهة مستخدم يتنقل للأعلى وللأسفل لإفساح المجال أمام لوحة مفاتيح

الشكل 1. الصور المتحركة لأداة IME

دعم داخلي لمكونات Material 3

لسهولة الاستخدام، يتعامل العديد من عناصر Material 3 المدمجة (androidx.compose.material3) مع المساحات الداخلية نفسها، بناءً على كيفية وضع العناصر القابلة للإنشاء في تطبيقك وفقًا لمواصفات Material.

عناصر قابلة للإنشاء أثناء معالجة البيانات الداخلية

وفي ما يلي قائمة بمكونات المواد التي تتعامل تلقائيًا مع الأجزاء الداخلية.

أشرطة التطبيقات

حاويات المحتوى

  • ModalDrawerSheet / DismissibleDrawerSheet / PermanentDrawerSheet (محتوى ضمن لائحة التنقّل المشروطة): يتم تطبيق مواضع الإعلانات الرأسية والبدء على المحتوى.
  • ModalBottomSheet: يتيح هذا الخيار تطبيق المجموعات الداخلية أسفل.
  • NavigationBar : يطبِّق هذا الإجراء كلاً من المجموعات الداخلية الأسفل والأفقية.
  • NavigationRail: يطبِّق هذا المقياس كلاً من شكل الإعلان الداخلي الفئة والبدء.

سقالة

توفِّر Scaffold تلقائيًا عناصر داخلية كمَعلمة paddingValues يمكنك استخدامها واستخدامها. لا تطبّق "Scaffold" التفاصيل على المحتوى، فهذه مسؤوليتك. على سبيل المثال، لاستخدام هذه المجموعات الداخلية مع LazyColumn داخل Scaffold:

Scaffold { innerPadding ->
    // innerPadding contains inset information for you to use and apply
    LazyColumn(
        // consume insets as scaffold doesn't do it by default
        modifier = Modifier.consumeWindowInsets(innerPadding),
        contentPadding = innerPadding
    ) {
        items(count = 100) {
            Box(
                Modifier
                    .fillMaxWidth()
                    .height(50.dp)
                    .background(colors[it % colors.size])
            )
        }
    }
}

إلغاء الإدخالات التلقائية

يمكنك تغيير معلَمة windowInsets التي تم تمريرها إلى العنصر القابل للإنشاء لضبط سلوك العنصر القابل للإنشاء. يمكن أن تكون هذه المعلَمة نوعًا مختلفًا من إدراج النافذة، أو يمكن إيقافها من خلال تمرير مثيل فارغ: WindowInsets(0, 0, 0, 0).

على سبيل المثال، لإيقاف معالجة الإدخال على LargeTopAppBar، اضبط مَعلمة windowInsets على مثيل فارغ:

LargeTopAppBar(
    windowInsets = WindowInsets(0, 0, 0, 0),
    title = {
        Text("Hi")
    }
)

إمكانية التشغيل التفاعلي مع إدراجات نظام "العرض"

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

على سبيل المثال، إذا كان التنسيق الخارجي هو تنسيق Android View، يجب أن تستهلك العناصر الداخلية في نظام العرض وتتجاهلها في Compose. بدلاً من ذلك، إذا كان التنسيق الخارجي قابلاً للإنشاء، يجب استخدام المجموعات في Compose وإدراج عناصر AndroidView القابلة للإنشاء وفقًا لذلك.

يتم استهلاك كل ComposeView تلقائيًا في كل مساحة تخزين عند مستوى الاستهلاك WindowInsetsCompat. لتغيير هذا السلوك التلقائي، اضبط السمة ComposeView.consumeWindowInsets على false.

المراجع

  • الآن في Android - تطبيق Android كامل الوظائف تم إنشاؤه بالكامل باستخدام Kotlin وJetpack Compose.