ट्रांज़िशन का इस्तेमाल करके, लेआउट में बदलावों को ऐनिमेट करें

Compose को आज़माएं
Jetpack Compose, Android के लिए यूज़र इंटरफ़ेस (यूआई) टूलकिट है. हम इसका इस्तेमाल करने का सुझाव देते हैं. Compose में ऐनिमेशन का इस्तेमाल करने का तरीका जानें.

Android का ट्रांज़िशन फ़्रेमवर्क, यूज़र इंटरफ़ेस (यूआई) में हर तरह की मोशन को ऐनिमेट करने की सुविधा देता है. इसके लिए, यह शुरुआती और खत्म होने वाले लेआउट उपलब्ध कराता है. आपके पास यह चुनने का विकल्प होता है कि आपको किस तरह का ऐनिमेशन चाहिए. जैसे, व्यू को फ़ेड इन या फ़ेड आउट करना या व्यू के साइज़ में बदलाव करना. ट्रांज़िशन फ़्रेमवर्क यह तय करता है कि शुरुआती लेआउट से खत्म होने वाले लेआउट तक ऐनिमेशन कैसे किया जाए.

ट्रांज़िशन फ़्रेमवर्क में ये सुविधाएं शामिल हैं:

  • ग्रुप-लेवल के ऐनिमेशन: व्यू हैरारकी में मौजूद सभी व्यू पर ऐनिमेशन इफ़ेक्ट लागू करना.
  • पहले से मौजूद ऐनिमेशन: फ़ेड आउट या मूवमेंट जैसे सामान्य इफ़ेक्ट के लिए, पहले से तय किए गए ऐनिमेशन का इस्तेमाल करना.
  • रिसॉर्स फ़ाइल की सुविधा: लेआउट रिसॉर्स फ़ाइलों से व्यू हैरारकी और पहले से मौजूद ऐनिमेशन लोड करना.
  • लाइफ़साइकल कॉलबैक: ऐसे कॉलबैक पाना जिनसे ऐनिमेशन और हैरारकी में बदलाव की प्रोसेस को कंट्रोल किया जा सकता है.

लेआउट में बदलाव के बीच ऐनिमेशन करने वाला सैंपल कोड देखने के लिए, BasicTransition देखें.

दो लेआउट के बीच ऐनिमेशन करने की बुनियादी प्रोसेस इस तरह है:

  1. शुरुआती और खत्म होने वाले लेआउट के लिए, Scene ऑब्जेक्ट बनाएं. हालांकि, शुरुआती लेआउट का सीन अक्सर मौजूदा लेआउट से अपने-आप तय हो जाता है.
  2. Transition ऑब्जेक्ट बनाएं, ताकि यह तय किया जा सके कि आपको किस तरह का ऐनिमेशन चाहिए.
  3. TransitionManager.go() को कॉल करें. इसके बाद, सिस्टम लेआउट को स्वैप करने के लिए ऐनिमेशन चलाता है.

पहली इमेज में दिया गया डायग्राम, आपके लेआउट, सीन, ट्रांज़िशन, और फ़ाइनल ऐनिमेशन के बीच का संबंध दिखाता है.

पहली इमेज. ट्रांज़िशन फ़्रेमवर्क, ऐनिमेशन कैसे बनाता है, इसका बुनियादी उदाहरण.

सीन बनाना

सीन में, व्यू हैरारकी की स्थिति सेव होती है. इसमें सभी व्यू और उनकी प्रॉपर्टी की वैल्यू शामिल होती हैं. ट्रांज़िशन फ़्रेमवर्क, शुरुआती और खत्म होने वाले सीन के बीच ऐनिमेशन चला सकता है.

आपके पास लेआउट रिसॉर्स फ़ाइल या अपने कोड में व्यू के ग्रुप से सीन बनाने का विकल्प होता है. हालांकि, आपके ट्रांज़िशन के लिए शुरुआती सीन अक्सर मौजूदा यूज़र इंटरफ़ेस (यूआई) से अपने-आप तय हो जाता है.

सीन, अपनी कार्रवाइयां भी तय कर सकता है. ये कार्रवाइयां, सीन में बदलाव करने पर चलती हैं. यह सुविधा, किसी सीन पर ट्रांज़िशन करने के बाद, व्यू सेटिंग को साफ़ करने में काम आती है.

लेआउट रिसॉर्स से सीन बनाना

आपके पास सीधे लेआउट रिसॉर्स फ़ाइल से 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" >
    <TextView
        android:id="@+id/text_view1"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Text Line 1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>
    <TextView
        android:id="@+id/text_view2"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Text Line 2"
        app:layout_constraintTop_toBottomOf="@id/text_view1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="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" >
    <TextView
        android:id="@+id/text_view2"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Text Line 2"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
    <TextView
        android:id="@+id/text_view1"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Text Line 1"
        app:layout_constraintTop_toBottomOf="@id/text_view2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="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 ऑब्जेक्ट हैं. दोनों सीन, res/layout/activity_main.xml में मौजूद FrameLayout एलिमेंट से तय किए गए सीन रूट का इस्तेमाल करते हैं.

अपने कोड में सीन बनाना

आपके पास ViewGroup ऑब्जेक्ट से, अपने कोड में Scene इंस्टेंस बनाने का विकल्प भी होता है. इस तकनीक का इस्तेमाल तब करें, जब अपने कोड में सीधे व्यू हैरारकी में बदलाव किया जाता है या जब उन्हें डाइनैमिक तौर पर जनरेट किया जाता है.

अपने कोड में व्यू हैरारकी से सीन बनाने के लिए, 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 ऑब्जेक्ट की मदद से सीन के बीच ऐनिमेशन का स्टाइल दिखाता है. पहले से मौजूद सबक्लास, जैसे कि AutoTransition और Fade का इस्तेमाल करके, Transition को इंस्टैंशिएट किया जा सकता है. इसके अलावा, अपना ट्रांज़िशन भी तय किया जा सकता है. इसके बाद, सीन के बीच ऐनिमेशन चलाया जा सकता है. इसके लिए, खत्म होने वाले Scene और Transition को TransitionManager.go() में पास करें.

ट्रांज़िशन लाइफ़साइकल, ऐक्टिविटी लाइफ़साइकल की तरह होती है. यह ट्रांज़िशन की उन स्थितियों को दिखाती है जिन्हें फ़्रेमवर्क, ऐनिमेशन के शुरू होने और खत्म होने के बीच मॉनिटर करता है. लाइफ़साइकल की अहम स्थितियों में, फ़्रेमवर्क कॉलबैक फ़ंक्शन को लागू करता है. इनका इस्तेमाल, ट्रांज़िशन के अलग-अलग चरणों में अपने यूज़र इंटरफ़ेस (यूआई) को अडजस्ट करने के लिए किया जा सकता है.

ट्रांज़िशन बनाना

पिछले सेक्शन में, अलग-अलग व्यू हैरारकी की स्थिति दिखाने वाले सीन बनाने का तरीका बताया गया है. बदलाव के लिए शुरुआती और खत्म होने वाले सीन तय करने के बाद, 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/ डायरेक्ट्री जोड़ें.
  • इस डायरेक्ट्री में, नई एक्सएमएल रिसॉर्स फ़ाइल बनाएं.
  • पहले से मौजूद किसी एक ट्रांज़िशन के लिए, एक्सएमएल नोड जोड़ें.

उदाहरण के लिए, यहां दी गई रिसॉर्स फ़ाइल में 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 क्लास के लिए एपीआई रेफ़रंस देखें.

एक से ज़्यादा ट्रांज़िशन तय करना

ऐनिमेशन से ज़्यादा से ज़्यादा असर पाने के लिए, इसे सीन के बीच होने वाले बदलावों के टाइप से मैच करें. उदाहरण के लिए, अगर सीन के बीच कुछ व्यू हटाए जा रहे हैं और कुछ जोड़े जा रहे हैं, तो फ़ेड आउट या फ़ेड इन ऐनिमेशन से यह साफ़ तौर पर पता चलता है कि कुछ व्यू अब उपलब्ध नहीं हैं. अगर व्यू को स्क्रीन पर अलग-अलग पॉइंट पर ले जाया जा रहा है, तो मूवमेंट को ऐनिमेट करना बेहतर है, ताकि उपयोगकर्ताओं को व्यू की नई जगह के बारे में पता चल सके.

सिर्फ़ एक ऐनिमेशन चुनने की ज़रूरत नहीं है, क्योंकि ट्रांज़िशन फ़्रेमवर्क, ऐनिमेशन इफ़ेक्ट को ट्रांज़िशन सेट में जोड़ने की सुविधा देता है. इस सेट में, पहले से मौजूद या कस्टम ट्रांज़िशन का ग्रुप शामिल होता है.

एक्सएमएल में ट्रांज़िशन के कलेक्शन से ट्रांज़िशन सेट तय करने के लिए, 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 पर लागू किया जाए.
  • ListView जैसी AdapterView से एक्सटेंड होने वाली क्लास, अपने चाइल्ड व्यू को ऐसे तरीकों से मैनेज करती हैं जो ट्रांज़िशन फ़्रेमवर्क के साथ काम नहीं करते. AdapterView के आधार पर किसी व्यू को ऐनिमेट करने की कोशिश करने पर, डिवाइस की स्क्रीन काम करना बंद कर सकती है.
  • किसी TextView को ऐनिमेशन के साथ रीसाइज़ करने की कोशिश करने पर, ऑब्जेक्ट के पूरी तरह रीसाइज़ होने से पहले, टेक्स्ट नई जगह पर पॉप अप हो जाता है. इस समस्या से बचने के लिए, टेक्स्ट वाले व्यू को रीसाइज़ करने के लिए ऐनिमेशन का इस्तेमाल न करें.