تعديل المشاهد باستخدام أدوات تزيين المشاهد

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

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

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

إنشاء استراتيجية لتزيين المشاهد

تتّبع أدوات تزيين المشاهد نمطًا مشابهًا لاستراتيجيات المشاهد. لتحديد مزيّن مشهد، نفِّذ واجهة SceneDecoratorStrategy. تحتوي هذه الواجهة على طريقة decorateScene، وهي مشابهة لطريقة calculateScene في واجهة SceneStrategy. يحدّد decorateScene ما إذا كان بإمكانه تزيين المشهد:

  • إذا كانت استراتيجية تزيين المشهد لا يجب أن تزيّن المشهد المُدخل، فإنّها تعرض المشهد المُدخل كما هو.
  • إذا كان يجب تزيين المشهد المُدخل، يتم عرض Scene جديد. بشكل عام، يأخذ المشهد الذي يتم عرضه المشهد المُدخل كمَعلمة ويستدعي طريقة content الخاصة بالمشهد المُدخل ضمن طريقة content الخاصة به.

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

class MySceneDecoratorStrategy<T : Any> : SceneDecoratorStrategy<T> {


    override fun SceneDecoratorStrategyScope<T>.decorateScene(scene: Scene<T>): Scene<T> {
        // `shouldDecorate` determines if the scene should be decorated based on scene.metadata,
        // scene.entries.metadata, or any other relevant state.
        return if (shouldDecorate(scene)) {
            MyDecoratingScene(scene)
        } else {
            scene
        }
    }

}

data class MyDecoratingScene<T : Any>(
    val scene: Scene<T>
) : Scene<T> {

    // ...

    override val content = @Composable {
        scene.content()
    }
}

استخدام استراتيجيات تزيين المشهد

لاستخدام استراتيجيات تزيين المشاهد، يمكنك تقديمها إلى NavDisplay باستخدام مَعلمة sceneDecoratorStrategies. عند تزيين المشاهد، يستدعي NavDisplay الطريقة decorateScene لكل استراتيجية على التوالي، ويمرّر ناتج كل استدعاء كمدخل للاستدعاء التالي.

NavDisplay(
    // ...
    sceneDecoratorStrategies = listOf(firstSceneDecoratorStrategy, secondSceneDecoratorStrategy)
)

الأنماط الشائعة لمصمّمي المشاهد

عند تنفيذ عناصر تزيين المشهد، إليك بعض الأنماط الشائعة التي يجب الانتباه إليها:

نسخ الخصائص

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

data class CopyingScene<T : Any>(
    val scene: Scene<T>
) : Scene<T> {
    override val entries = scene.entries
    override val previousEntries = scene.previousEntries
    override val metadata = scene.metadata

    // ...
}

الحفاظ على الصور المتحركة

As detailed in Animate between destinations, NavDisplay automatically animates transitions between scenes when a key derived from the class of the current scene and its key property changes.

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

To maintain built-in animation support, decorating scenes should use a key derived from the class and key of the scene returned by calculateScene.

data class DerivedKeyScene<T : Any>(
    val scene: Scene<T>
) : Scene<T> {
    override val key = scene::class to scene.key

    // ...
}