تحريك تغييرات التنسيق باستخدام عملية نقل

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

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

يتضمّن إطار عمل النقل الميزات التالية:

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

للاطّلاع على نموذج للرمز البرمجي الذي يتحرك بين تغييرات التنسيق، يُرجى الاطّلاع على BasicTransition.

في ما يلي العملية الأساسية لإنشاء تأثيرات متحركة بين تنسيقَين:

  1. أنشئ عنصر Scene لملفَي التنسيق البدء والانتهاء. ومع ذلك، يتم تحديد المشهد في التنسيق الأساسي غالبًا تلقائيًا من التنسيق الحالي.
  2. أنشئ عنصر Transition لتحديد نوع الحركة التي تريدها.
  3. اتصل بالرقم TransitionManager.go()، ويعمل النظام على تشغيل الصورة المتحركة لتبديل التنسيقات.

يوضِّح الرسم البياني في الشكل 1 العلاقة بين التنسيقات والمشاهد والانتقال والصورة المتحركة النهائية.

الشكل 1: صورة توضيحية أساسية لكيفية إنشاء إطار العمل الانتقالي لرسم متحرك

إنشاء مشهد

تخزِّن المشاهد حالة التسلسل الهرمي للعرض، بما في ذلك جميع مشاهده و قيم مَعلماته. يمكن لإطار عمل الانتقالات تشغيل الرسوم المتحركة بين مشهد البداية والنهاية.

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

يمكن أن يحدِّد المشهد أيضًا الإجراءات التي يتم تنفيذها عند إجراء تغيير في المشهد. تُعد هذه الميزة مفيدة لتنظيف إعدادات العرض بعد الانتقال إلى المشهد.

إنشاء مشهد من مرجع تنسيق

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

لإنشاء مثيل Scene من ملف مورد تنسيق، استرجع جذر المشهد من التنسيق على هيئة ViewGroup. بعد ذلك، استخدِم الدالة Scene.getSceneForLayout() مع جذر المشهد ورقم تعريف المورد لملف التنسيق الذي يحتوي على التسلسل الهرمي للعرض للمشهد.

تحديد تنسيقات للمشاهد

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

يتألّف المثال من تعريفات التنسيق التالية:

  • التنسيق الرئيسي لنشاط يتضمّن تصنيف نصي ونشاطًا فرعيًا FrameLayout.
  • تمثل هذه السمة ConstraintLayout للمشهد الأول مع حقلي نص.
  • تمثل هذه السمة ConstraintLayout للمشهد الثاني مع نفس الحقلين النصيين بترتيب مختلف.

تم تصميم المثال بحيث تحدث جميع الرسوم المتحركة داخل التخطيط الثانوي للتخطيط الرئيسي للنشاط. يظل تصنيف النص في التنسيق الرئيسي ثابتًا.

يتم تحديد التنسيق الرئيسي للنشاط على النحو التالي:

res/layout/activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/master_layout">
    <TextView
        android:id="@+id/title"
        ...
        android:text="Title"/>
    <FrameLayout
        android:id="@+id/scene_root">
        <include layout="@layout/a_scene" />
    </FrameLayout>
</LinearLayout>

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

يتمّ تحديد تنسيق المشهد الأوّل على النحو التالي:

res/layout/a_scene.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/scene_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    
</androidx.constraintlayout.widget.ConstraintLayout>

يحتوي تخطيط المشهد الثاني على نفس الحقلين النصيين - مع نفس المعرفات - موضوعة بترتيب مختلف. ويتم تعريفها على النحو التالي:

res/layout/another_scene.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/scene_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    
</androidx.constraintlayout.widget.ConstraintLayout>

إنشاء مَشاهد من التنسيقات

بعد إنشاء تعريفات لتنسيقَي القيود، يمكنك الحصول على مشهد لكل منهما. يتيح لك ذلك الانتقال بين ملفَي تكوين واجهة المستخدِم. للحصول على مشهد، يجب الإشارة إلى جذر المشهد ورقم تعريف مورد التصميم.

يوضّح المقتطف التالي من الرمز البرمجي كيفية الحصول على إشارة إلى جذر المشهد و إنشاء عنصرَي Scene من ملفات التنسيق:

Kotlin

val sceneRoot: ViewGroup = findViewById(R.id.scene_root)
val aScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this)
val anotherScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this)

Java

Scene aScene;
Scene anotherScene;

// Create the scene root for the scenes in this app.
sceneRoot = (ViewGroup) findViewById(R.id.scene_root);

// Create the scenes.
aScene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this);
anotherScene =
    Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this);

في التطبيق، يتوفّر الآن عنصرَان Scene استنادًا إلى التدرّجات الهرمية للعرض. يستخدم كلا المشهدَين جذر المشهد الذي يحدّده العنصر FrameLayout في res/layout/activity_main.xml.

إنشاء مشهد في الرمز البرمجي

يمكنك أيضًا إنشاء مثيل Scene في الرمز البرمجي من كائن ViewGroup. استخدِم هذه التقنية عند تعديل تسلسلات العرض المُدرَجة في الرمز البرمجي مباشرةً أو عند إنشائها ديناميكيًا.

لإنشاء مشهد من تدرج هرمي للعرض في الرمز البرمجي، استخدِم الدالة الإنشائية Scene(sceneRoot, viewHierarchy). إنّ استدعاء هذا المُنشئ يعادل استدعاء الدالة Scene.getSceneForLayout() بعد تضخيم ملف تنسيق.

يوضّح مقتطف الرمز التالي كيفية إنشاء مثيل Scene من عنصر جذر المشهد والتسلسل الهرمي للعرض للمشهد في الرمز البرمجي:

Kotlin

val sceneRoot = someLayoutElement as ViewGroup
val viewHierarchy = someOtherLayoutElement as ViewGroup
val scene: Scene = Scene(sceneRoot, viewHierarchy)

Java

Scene mScene;

// Obtain the scene root element.
sceneRoot = (ViewGroup) someLayoutElement;

// Obtain the view hierarchy to add as a child of
// the scene root when this scene is entered.
viewHierarchy = (ViewGroup) someOtherLayoutElement;

// Create a scene.
mScene = new Scene(sceneRoot, mViewHierarchy);

إنشاء إجراءات للمشهد

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

تكون إجراءات المشهد مفيدة في التعامل مع الحالات التالية:

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

لتقديم إجراءات مخصّصة للمشهد، حدِّد إجراءاتك على أنّها عناصر Runnable وأرسِلها إلى الدالتَين Scene.setExitAction() أو Scene.setEnterAction(). يستدعي إطار العمل الدالة setExitAction() في مشهد البداية قبل تشغيل حركة الانتقال، والوظيفة setEnterAction() في مشهد النهاية بعد تشغيل حركة الانتقال.

تطبيق تأثير انتقال

يمثّل إطار الانتقال الانتقالي نمط الحركة بين المَشاهد باستخدام كائن Transition. يمكنك إنشاء مثيل Transition باستخدام klassen الفرعية المضمّنة، مثل AutoTransition و Fade، أو تحديد انتقالك الخاص. بعد ذلك، يمكنك عرض الرسوم المتحركة بين المشاهد من خلال تمرير النهاية Scene وTransition إلى TransitionManager.go().

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

إنشاء انتقال

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

الجدول 1: أنواع الانتقالات المضمّنة

الفئة الإشارة التأثير
AutoTransition <autoTransition/> الانتقال التلقائي يتلاشى تدريجيًا ويتحرك ويغيّر حجمه، ويتلاشى في طرق العرض، بهذا الترتيب.
ChangeBounds <changeBounds/> نقل طرق العرض وتغيير حجمها
ChangeClipBounds <changeClipBounds/> يتم استخدام هذه الميزة لتصوير View.getClipBounds() قبل تغيير المشهد وبعده، وإضافة مؤثرات حركية إليه أثناء الانتقال.
ChangeImageTransform <changeImageTransform/> تلتقط مصفوفة ImageView قبل تغيُّر المشهد وبعده وتضيف إليها الحركة أثناء عملية النقل.
ChangeScroll <changeScroll/> يلتقط خصائص التمرير للأهداف قبل تغيير المشهد وبعده، ويحرّك أي تغييرات.
ChangeTransform <changeTransform/> تلتقط هذه الميزة حجم اللقطات واتجاهها قبل تغيير المشهد وبعده، وتضيف تأثيرًا متحركًا إلى هذه التغييرات أثناء الانتقال.
Explode <explode/> تتتبّع التغييرات في مستوى رؤية المَشاهد المستهدَفة في المَشاهد التمهيدية والختامية، وتنقل المَشاهد إلى داخل أو خارج حواف المشهد.
Fade <fade/> fade_in يتلاشى في المشاهدات.
fade_out التلاشي للمشاهدات
fade_in_out (تلقائي) يُجري fade_out متبوعًا بـ fade_in.
Slide <slide/> تتبّع التغييرات في مستوى رؤية المَشاهد المستهدَفة في المَشاهد المُبدئية والختامية وتنقل المَشاهد إلى الداخل أو الخارج من إحدى حواف المشهد.

إنشاء مثيل انتقال من ملف موارد

تتيح لك هذه التقنية تعديل تعريف الانتقال بدون تغيير رمز نشاطك. يُعدّ هذا الأسلوب مفيدًا أيضًا لفصل تعريفات التحولات المعقدة عن رمز تطبيقك، كما هو موضّح في القسم المعنيّ بتحديد التحولات المتعدّدة.

لتحديد انتقال مضمّن في ملف موارد، اتّبِع الخطوات التالية:

  • أضِف دليل res/transition/ إلى مشروعك.
  • أنشئ ملف موارد XML جديدًا داخل هذا الدليل.
  • أضِف عقدة XML لأحد الانتقالات المضمّنة.

على سبيل المثال، يحدّد ملف المورد التالي عملية النقل Fade:

res/transition/fade_transition.xml

<fade xmlns:android="http://schemas.android.com/apk/res/android" />

يوضّح المقتطف التالي من الرمز البرمجي كيفية تضخيم مثيل Transition داخل نشاطك من ملف موارد:

Kotlin

var fadeTransition: Transition =
    TransitionInflater.from(this)
                      .inflateTransition(R.transition.fade_transition)

Java

Transition fadeTransition =
        TransitionInflater.from(this).
        inflateTransition(R.transition.fade_transition);

إنشاء مثيل انتقال في التعليمة البرمجية

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

لإنشاء مثيل لعملية انتقال مضمّنة، استخدِم أحد مثبّتي القيمة العلنيين في الفئات الفرعية لفئة Transition. على سبيل المثال، ينشئ مقتطف الرمز البرمجي التالي مثيلًا للانتقال Fade:

Kotlin

var fadeTransition: Transition = Fade()

Java

Transition fadeTransition = new Fade();

تطبيق تأثير انتقال

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

لتغيير المشهد أثناء تطبيق انتقال استجابةً لحدث في نشاطك، استدعِ دالة الفئة TransitionManager.go() التي تحتوي على مشهد النهاية ومثيل الانتقال لاستخدامهما مع الرسوم المتحركة، كما هو موضّح في المقتطف التالي:

Kotlin

TransitionManager.go(endingScene, fadeTransition)

Java

TransitionManager.go(endingScene, fadeTransition);

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

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

اختيار مشاهدات مستهدَفة معيّنة

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

يُطلق على كل ملف شخصي يحرّكه الانتقال اسم هدف. يمكنك فقط اختيار الاستهدافات التي تشكّل جزءًا من التسلسل الهرمي للعرض المرتبط بمشهد.

لإزالة عرض واحد أو أكثر من قائمة الاستهدافات، استخدِم الأسلوب removeTarget() قبل بدء عملية النقل. لإضافة العروض التي تحدّدها فقط إلى قائمة الاستهدافات، استخدِم الدالة addTarget(). لمزيد من المعلومات، اطّلِع على مرجع واجهة برمجة التطبيقات لفئة Transition.

تحديد عدّة انتقالات

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

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

لتحديد مجموعة انتقالات من مجموعة من الانتقالات في XML، أنشِئ ملف موارد في دليل res/transitions/ وأدرِج الانتقالات ضمن العنصر TransitionSet. على سبيل المثال، يوضّح المقتطف التالي كيفية تحديد مجموعة انتقالات لها السلوك نفسه مثل فئة AutoTransition:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    android:transitionOrdering="sequential">
    <fade android:fadingMode="fade_out" />
    <changeBounds />
    <fade android:fadingMode="fade_in" />
</transitionSet>

لتضخيم مجموعة الانتقالات إلى عنصر TransitionSet في الرمز البرمجي، استخدِم الدالة TransitionInflater.from() في نشاطك. تمتد الفئة TransitionSet من الفئة Transition، لذا يمكنك استخدامها مع مدير نقل مثل أي مثيل Transition آخر.

تطبيق انتقال بدون مَشاهد

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

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

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

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

لإنشاء انتقال متأخر ضمن تسلسل هرمي واحد للعرض، اتّبِع الخطوات التالية:

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

يعرض المثال التالي كيفية إضافة عرض نصي إلى التسلسل الهرمي للعرض باستخدام انتقال متأخر. يعرض المقتطف الأول ملف تعريف ملف التنسيق:

res/layout/activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <EditText
        android:id="@+id/inputText"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
    ...
</androidx.constraintlayout.widget.ConstraintLayout>

يعرض المقتطف التالي الرمز الذي يضيف تأثيرًا متحركًا إلى طريقة عرض النص:

MainActivity

Kotlin

setContentView(R.layout.activity_main)
val labelText = TextView(this).apply {
    text = "Label"
    id = R.id.text
}
val rootView: ViewGroup = findViewById(R.id.mainLayout)
val mFade: Fade = Fade(Fade.IN)
TransitionManager.beginDelayedTransition(rootView, mFade)
rootView.addView(labelText)

Java

private TextView labelText;
private Fade mFade;
private ViewGroup rootView;
...
// Load the layout.
setContentView(R.layout.activity_main);
...
// Create a new TextView and set some View properties.
labelText = new TextView(this);
labelText.setText("Label");
labelText.setId(R.id.text);

// Get the root view and create a transition.
rootView = (ViewGroup) findViewById(R.id.mainLayout);
mFade = new Fade(Fade.IN);

// Start recording changes to the view hierarchy.
TransitionManager.beginDelayedTransition(rootView, mFade);

// Add the new TextView to the view hierarchy.
rootView.addView(labelText);

// When the system redraws the screen to show this update,
// the framework animates the addition as a fade in.

تحديد وظائف الاستدعاء في مراحل نشاط الانتقال

تشبه مراحل النقل مراحل النشاط. ويمثّل حالات النقل التي يراقبها الإطار خلال الفترة بين دعوة لدالة TransitionManager.go() وإكمال الصورة المتحركة. في حالات مهمة من دورة الحياة، يستدعي إطار العمل وظائف الاستدعاء التي تحدّدها واجهة TransitionListener.

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

لمزيد من المعلومات، اطّلِع على مرجع واجهة برمجة التطبيقات لفئة TransitionListener.

القيود

يسرد هذا القسم بعض القيود المعروفة لإطار عمل الانتقالات:

  • قد لا تظهر الصور المتحركة المطبَّقة على SurfaceView بشكلٍ صحيح. يتم تعديل مثيلات SurfaceView من سلسلة محادثات لا تخصّ واجهة المستخدم، لذا قد لا تكون التعديلات متزامنة مع الصور المتحركة لطرق العرض الأخرى.
  • قد لا تؤدي بعض أنواع الانتقالات المحدّدة إلى ظهور تأثير الرسوم المتحركة المطلوب عند تطبيقها على TextureView.
  • الفصول التي تمتد من AdapterView، مثل ListView، تدير طرق عرضها الفرعية بطرق غير متوافقة مع إطار عمل الانتقالات. إذا حاولت إضافة تأثيرات متحركة إلى عرض استنادًا إلى AdapterView، قد تتوقف شاشة الجهاز عن الاستجابة.
  • إذا حاولت تغيير حجم TextView باستخدام صورة متحركة، سيظهر النص في مكان جديد قبل أن يتم تغيير حجم الكائن بالكامل. لتجنُّب هذه المشكلة، لا تضِف تأثيرًا متحركًا لتغيير حجم المشاهدات التي تحتوي على نص.