प्रॉपर्टी ऐनिमेशन की खास जानकारी

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

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

प्रॉपर्टी ऐनिमेशन सिस्टम की मदद से, ऐनिमेशन की इन विशेषताओं के बारे में बताया जा सकता है:

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

प्रॉपर्टी ऐनिमेशन का पूरा उदाहरण देखने के लिए, GitHub पर CustomTransition सैंपल में मौजूद ChangeColor क्लास देखें.

प्रॉपर्टी ऐनिमेशन कैसे काम करता है

सबसे पहले, एक आसान उदाहरण से समझते हैं कि ऐनिमेशन कैसे काम करता है. पहली इमेज में, एक काल्पनिक ऑब्जेक्ट दिखाया गया है. इसे इसकी x प्रॉपर्टी के साथ ऐनिमेट किया गया है. यह प्रॉपर्टी, स्क्रीन पर इसकी हॉरिज़ॉन्टल लोकेशन दिखाती है. ऐनिमेशन की अवधि 40 मि॰से॰ पर सेट की गई है और दूरी 40 पिक्सल पर सेट की गई है. हर 10 मि॰से॰ में ऑब्जेक्ट, 10 पिक्सल तक हॉरिज़ॉन्टल तौर पर मूव करता है. यह फ़्रेम रीफ़्रेश होने की डिफ़ॉल्ट दर है. 40 मि॰से॰ के बाद, ऐनिमेशन रुक जाता है और ऑब्जेक्ट हॉरिज़ॉन्टल पोज़िशन 40 पर खत्म होता है. यह लीनियर इंटरपोलेशन वाले ऐनिमेशन का उदाहरण है. इसका मतलब है कि ऑब्जेक्ट एक ही स्पीड से मूव करता है.

पहली इमेज. लीनियर ऐनिमेशन का उदाहरण

नॉन-लीनियर इंटरपोलेशन के लिए, ऐनिमेशन भी तय किए जा सकते हैं. दूसरी इमेज में, एक काल्पनिक ऑब्जेक्ट दिखाया गया है. इसमें ऐनिमेशन की शुरुआत में ऑब्जेक्ट की रफ़्तार बढ़ती है और ऐनिमेशन के आखिर में रफ़्तार कम होती है. ऑब्जेक्ट अब भी 40 मिलीसेकंड में 40 पिक्सल आगे बढ़ता है, लेकिन यह लीनियर तरीके से नहीं होता. शुरुआत में, यह ऐनिमेशन आधे रास्ते तक तेज़ी से आगे बढ़ता है. इसके बाद, आधे रास्ते से लेकर ऐनिमेशन के खत्म होने तक इसकी रफ़्तार कम होती जाती है. जैसा कि दूसरे डायग्राम में दिखाया गया है, ऐनिमेशन की शुरुआत और आखिर में तय की गई दूरी, बीच में तय की गई दूरी से कम है.

दूसरी इमेज. नॉन-लीनियर ऐनिमेशन का उदाहरण

आइए, प्रॉपर्टी ऐनिमेशन सिस्टम के अहम कॉम्पोनेंट के बारे में विस्तार से जानते हैं. ये कॉम्पोनेंट, ऊपर दिखाए गए ऐनिमेशन जैसे ऐनिमेशन का हिसाब कैसे लगाते हैं. तीसरी इमेज में दिखाया गया है कि मुख्य क्लास एक-दूसरे के साथ कैसे काम करती हैं.

तीसरी इमेज. ऐनिमेशन का हिसाब कैसे लगाया जाता है

ValueAnimator ऑब्जेक्ट, आपके ऐनिमेशन के समय को ट्रैक करता है. जैसे, ऐनिमेशन कितने समय से चल रहा है और जिस प्रॉपर्टी को ऐनिमेट किया जा रहा है उसकी मौजूदा वैल्यू क्या है.

ValueAnimator में TimeInterpolator शामिल होता है. यह ऐनिमेशन इंटरपोलेशन तय करता है. साथ ही, इसमें TypeEvaluator भी शामिल होता है. यह बताता है कि ऐनिमेशन की जा रही प्रॉपर्टी के लिए वैल्यू की गणना कैसे की जाए. उदाहरण के लिए, इमेज 2 में इस्तेमाल किया गया TimeInterpolator, AccelerateDecelerateInterpolator होगा और TypeEvaluator, IntEvaluator होगा.

ऐनिमेशन शुरू करने के लिए, एक ValueAnimator बनाएं. इसके बाद, उस प्रॉपर्टी के लिए शुरुआती और आखिरी वैल्यू दें जिसे आपको ऐनिमेट करना है. साथ ही, ऐनिमेशन की अवधि भी तय करें. start() पर कॉल करने पर, ऐनिमेशन शुरू हो जाता है. पूरे ऐनिमेशन के दौरान, ValueAnimator, 0 से 1 के बीच बीता हुआ फ़्रैक्शन का हिसाब लगाता है. यह हिसाब, ऐनिमेशन की अवधि और बीते हुए समय के आधार पर लगाया जाता है. बीता हुआ फ़्रैक्शन, ऐनिमेशन के पूरे होने का प्रतिशत दिखाता है. 0 का मतलब 0% और 1 का मतलब 100% है. उदाहरण के लिए, पहले डायग्राम में, t = 10 मि॰से॰ पर बीता हुआ फ़्रैक्शन .25 होगा, क्योंकि कुल अवधि t = 40 मि॰से॰ है.

जब ValueAnimator, बीता हुआ फ़्रैक्शन कैलकुलेट कर लेता है, तो यह TimeInterpolator को कॉल करता है. इससे इंटरपोलेटेड फ़्रैक्शन कैलकुलेट किया जाता है. इंटरपोलेट किया गया फ़्रैक्शन, बीते हुए फ़्रैक्शन को एक नए फ़्रैक्शन पर मैप करता है. यह सेट किए गए समय के इंटरपोलेशन को ध्यान में रखता है. उदाहरण के लिए, इमेज 2 में, ऐनिमेशन की स्पीड धीरे-धीरे बढ़ती है. इसलिए, इंटरपोलेट किया गया फ़्रैक्शन, करीब .15, बीते हुए फ़्रैक्शन, .25 से कम है. यह t = 10 मि॰से॰ पर है. इमेज 1 में, इंटरपोलेट किया गया फ़्रैक्शन हमेशा बीते हुए फ़्रैक्शन के बराबर होता है.

जब इंटरपोलेटेड फ़्रैक्शन का हिसाब लगाया जाता है, तब ValueAnimator, सही TypeEvaluator को कॉल करता है. इससे, इंटरपोलेटेड फ़्रैक्शन, शुरुआती वैल्यू, और एनिमेशन की आखिरी वैल्यू के आधार पर, उस प्रॉपर्टी की वैल्यू का हिसाब लगाया जाता है जिसे आपको ऐनिमेट करना है. उदाहरण के लिए, इमेज 2 में t = 10 मि॰से॰ पर इंटरपोलेट किया गया फ़्रैक्शन .15 था. इसलिए, उस समय प्रॉपर्टी की वैल्यू .15 × (40 - 0) या 6 होगी.

प्रॉपर्टी ऐनिमेशन और व्यू ऐनिमेशन में क्या अंतर है

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

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

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

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

एपीआई के बारे में खास जानकारी

प्रॉपर्टी ऐनिमेशन सिस्टम के ज़्यादातर एपीआई, android.animation में देखे जा सकते हैं. व्यू ऐनिमेशन सिस्टम, android.view.animation में पहले से ही कई इंटरपोलेटर तय करता है. इसलिए, प्रॉपर्टी ऐनिमेशन सिस्टम में भी उन इंटरपोलेटर का इस्तेमाल किया जा सकता है. यहां दी गई टेबल में, प्रॉपर्टी ऐनिमेशन सिस्टम के मुख्य कॉम्पोनेंट के बारे में बताया गया है.

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

पहली टेबल. ऐनिमेशन बनाने वाले

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

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

टेबल 2. समीक्षा करने वाले लोग

क्लास/इंटरफ़ेस ब्यौरा
IntEvaluator int प्रॉपर्टी के लिए वैल्यू का हिसाब लगाने वाला डिफ़ॉल्ट कैलकुलेटर.
FloatEvaluator float प्रॉपर्टी के लिए वैल्यू का हिसाब लगाने वाला डिफ़ॉल्ट कैलकुलेटर.
ArgbEvaluator यह डिफ़ॉल्ट इवैल्यूएटर, रंग की उन प्रॉपर्टी के लिए वैल्यू कैलकुलेट करता है जिन्हें हेक्साडेसिमल वैल्यू के तौर पर दिखाया जाता है.
TypeEvaluator ऐसा इंटरफ़ेस जिसकी मदद से, अपना खुद का आकलन करने वाला टूल बनाया जा सकता है. अगर आपको किसी ऐसी ऑब्जेक्ट प्रॉपर्टी को ऐनिमेट करना है जो int, float या रंग नहीं है, तो आपको TypeEvaluator इंटरफ़ेस लागू करना होगा. इससे यह तय किया जा सकेगा कि ऑब्जेक्ट प्रॉपर्टी की ऐनिमेट की गई वैल्यू कैसे कैलकुलेट की जाएं. अगर आपको int, float, और रंग की वैल्यू को डिफ़ॉल्ट तरीके से अलग तरीके से प्रोसेस करना है, तो आपके पास उनके लिए कस्टम TypeEvaluator तय करने का विकल्प भी है. कस्टम इवैल्यूएटर लिखने के तरीके के बारे में ज़्यादा जानकारी के लिए, TypeEvaluator का इस्तेमाल करना सेक्शन देखें.

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

तीसरी टेबल. इंटरपोलेटर

क्लास/इंटरफ़ेस ब्यौरा
AccelerateDecelerateInterpolator यह एक ऐसा इंटरपोलेटर है जिसकी दर में बदलाव धीरे-धीरे शुरू होता है और धीरे-धीरे खत्म होता है. हालांकि, बीच में इसकी दर बढ़ जाती है.
AccelerateInterpolator यह एक ऐसा इंटरपोलेटर है जिसकी बदलाव की दर धीरे-धीरे शुरू होती है और फिर तेज़ हो जाती है.
AnticipateInterpolator यह एक ऐसा इंटरपोलेटर है जो पीछे की ओर से शुरू होता है और फिर आगे की ओर बढ़ता है.
AnticipateOvershootInterpolator यह एक ऐसा इंटरपोलेटर है जिसकी वैल्यू में बदलाव पीछे की ओर से शुरू होता है. इसके बाद, यह आगे की ओर बढ़ता है और टारगेट वैल्यू से ज़्यादा हो जाता है. आखिर में, यह वापस फ़ाइनल वैल्यू पर आ जाता है.
BounceInterpolator ऐसा इंटरपोलेटर जिसकी वैल्यू आखिर में उछलती है.
CycleInterpolator यह एक इंटरपोलेटर है, जिसका ऐनिमेशन तय किए गए साइकल की संख्या के हिसाब से दोहराता है.
DecelerateInterpolator यह एक ऐसा इंटरपोलेटर है जिसमें बदलाव की दर तेज़ी से शुरू होती है और फिर धीरे-धीरे कम हो जाती है.
LinearInterpolator यह एक ऐसा इंटरपोलेटर है जिसकी बदलाव की दर स्थिर होती है.
OvershootInterpolator यह एक ऐसा इंटरपोलेटर है जिसकी वैल्यू में तेज़ी से बदलाव होता है और यह आखिरी वैल्यू से आगे बढ़ जाती है. इसके बाद, यह वापस आ जाती है.
TimeInterpolator यह एक ऐसा इंटरफ़ेस है जिसकी मदद से, अपना इंटरपोलेटर लागू किया जा सकता है.

ValueAnimator का इस्तेमाल करके ऐनिमेट करना

ValueAnimator क्लास की मदद से, किसी ऐनिमेशन की अवधि के लिए कुछ टाइप की वैल्यू को ऐनिमेट किया जा सकता है. इसके लिए, आपको int, float या रंग की वैल्यू का सेट तय करना होगा. ValueAnimator को इसके फ़ैक्ट्री के किसी एक तरीके को कॉल करके हासिल किया जाता है: ofInt(), ofFloat() या ofObject(). उदाहरण के लिए:

Kotlin

ValueAnimator.ofFloat(0f, 100f).apply {
    duration = 1000
    start()
}

Java

ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f);
animation.setDuration(1000);
animation.start();

इस कोड में, ValueAnimator तरीके के चलने पर, ValueAnimator, 1000 मि॰से॰ की अवधि के लिए, 0 से 100 के बीच ऐनिमेशन की वैल्यू का हिसाब लगाना शुरू करता है.start()

एनिमेशन के लिए कस्टम टाइप भी तय किया जा सकता है. इसके लिए, यह तरीका अपनाएं:

Kotlin

ValueAnimator.ofObject(MyTypeEvaluator(), startPropertyValue, endPropertyValue).apply {
    duration = 1000
    start()
}

Java

ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();

इस कोड में, start() तरीके के चलने पर, ValueAnimator, startPropertyValue और endPropertyValue के बीच ऐनिमेशन की वैल्यू का हिसाब लगाना शुरू कर देता है. इसके लिए, MyTypeEvaluator से मिले लॉजिक का इस्तेमाल किया जाता है. यह प्रोसेस 1000 मि॰से॰ तक चलती है.

ValueAnimator ऑब्जेक्ट में AnimatorUpdateListener जोड़कर, ऐनिमेशन की वैल्यू का इस्तेमाल किया जा सकता है. इसके लिए, यहां दिया गया कोड देखें:

Kotlin

ValueAnimator.ofObject(...).apply {
    ...
    addUpdateListener { updatedAnimation ->
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        textView.translationX = updatedAnimation.animatedValue as Float
    }
    ...
}

Java

animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

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

ObjectAnimator का इस्तेमाल करके ऐनिमेट करना

ObjectAnimator, ValueAnimator (पिछले सेक्शन में इसके बारे में बताया गया है) की सबक्लास है. इसमें ValueAnimator के टाइमिंग इंजन और वैल्यू कंप्यूटेशन को, टारगेट ऑब्जेक्ट की नाम वाली प्रॉपर्टी को ऐनिमेट करने की सुविधा के साथ जोड़ा जाता है. इससे किसी भी ऑब्जेक्ट को ऐनिमेट करना बहुत आसान हो जाता है, क्योंकि अब आपको ValueAnimator.AnimatorUpdateListener को लागू करने की ज़रूरत नहीं है. ऐसा इसलिए, क्योंकि ऐनिमेट की गई प्रॉपर्टी अपने-आप अपडेट हो जाती है.

ObjectAnimator को इंस्टैंशिएट करना, ValueAnimator के जैसा ही होता है. हालांकि, आपको ऑब्जेक्ट और उस ऑब्जेक्ट की प्रॉपर्टी का नाम (स्ट्रिंग के तौर पर) भी तय करना होता है. साथ ही, उन वैल्यू के बारे में बताना होता है जिनके बीच ऐनिमेशन करना है:

Kotlin

ObjectAnimator.ofFloat(textView, "translationX", 100f).apply {
    duration = 1000
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f);
animation.setDuration(1000);
animation.start();

ObjectAnimator को प्रॉपर्टी की जानकारी सही तरीके से अपडेट करने के लिए, आपको यह काम करना होगा:

  • जिस ऑब्जेक्ट प्रॉपर्टी में ऐनिमेशन किया जा रहा है उसमें सेटर फ़ंक्शन (कैमल केस में) होना चाहिए. यह फ़ंक्शन, set<PropertyName>() के फ़ॉर्म में होना चाहिए. ObjectAnimator, ऐनिमेशन के दौरान प्रॉपर्टी को अपने-आप अपडेट करता है. इसलिए, इसके पास सेटर के इस तरीके से प्रॉपर्टी को ऐक्सेस करने की अनुमति होनी चाहिए. उदाहरण के लिए, अगर प्रॉपर्टी का नाम foo है, तो आपके पास setFoo() तरीका होना चाहिए. अगर यह सेटर तरीका मौजूद नहीं है, तो आपके पास तीन विकल्प हैं:
    • अगर आपके पास क्लास में सेटर मेथड जोड़ने का अधिकार है, तो उसे जोड़ें.
    • ऐसी रैपर क्लास का इस्तेमाल करें जिसमें बदलाव करने का आपके पास अधिकार हो. साथ ही, उस रैपर क्लास को मान्य सेटर तरीके से वैल्यू मिले और वह उसे ओरिजनल ऑब्जेक्ट को फ़ॉरवर्ड करे.
    • इसके बजाय, ValueAnimator का इस्तेमाल करें.
  • अगर आपने ObjectAnimator फ़ैक्ट्री के किसी एक तरीके में values... पैरामीटर के लिए सिर्फ़ एक वैल्यू तय की है, तो इसे ऐनिमेशन की आखिरी वैल्यू माना जाएगा. इसलिए, जिस ऑब्जेक्ट प्रॉपर्टी को ऐनिमेट किया जा रहा है उसमें एक गेटर फ़ंक्शन होना चाहिए. इसका इस्तेमाल, ऐनिमेशन की शुरुआती वैल्यू पाने के लिए किया जाता है. गेटर फ़ंक्शन get<PropertyName>() के फ़ॉर्मैट में होना चाहिए. उदाहरण के लिए, अगर प्रॉपर्टी का नाम foo है, तो आपके पास getFoo() तरीका होना चाहिए.
  • जिस प्रॉपर्टी को ऐनिमेट किया जा रहा है उसके लिए, getter (ज़रूरत पड़ने पर) और setter के तरीके, उसी टाइप पर काम करने चाहिए जिस टाइप की शुरुआती और आखिरी वैल्यू को ObjectAnimator में सेट किया गया है. उदाहरण के लिए, अगर आपको यह ObjectAnimator बनाना है, तो आपके पास targetObject.setPropName(float) और targetObject.getPropName() होना चाहिए:
    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
  • जिस प्रॉपर्टी या ऑब्जेक्ट को ऐनिमेट किया जा रहा है उसके आधार पर, आपको किसी व्यू पर invalidate() तरीके को कॉल करना पड़ सकता है. इससे स्क्रीन, ऐनिमेशन की अपडेट की गई वैल्यू के साथ खुद को फिर से रेंडर कर पाएगी. ऐसा onAnimationUpdate() कॉलबैक में किया जाता है. उदाहरण के लिए, किसी Drawable ऑब्जेक्ट की कलर प्रॉपर्टी को ऐनिमेट करने पर, स्क्रीन सिर्फ़ तब अपडेट होती है, जब वह ऑब्जेक्ट खुद को फिर से ड्रॉ करता है. View पर मौजूद सभी प्रॉपर्टी सेटर, जैसे कि setAlpha() और setTranslationX() व्यू को सही तरीके से अमान्य करते हैं. इसलिए, नई वैल्यू के साथ इन तरीकों को कॉल करते समय, आपको व्यू को अमान्य करने की ज़रूरत नहीं है. लिसनर के बारे में ज़्यादा जानने के लिए, ऐनिमेशन लिसनर सेक्शन देखें.

AnimatorSet का इस्तेमाल करके, एक से ज़्यादा ऐनिमेशन को कोरियोग्राफ़ करना

कई मामलों में, आपको ऐसा ऐनिमेशन चलाना होता है जो इस बात पर निर्भर करता है कि दूसरा ऐनिमेशन कब शुरू होता है या कब खत्म होता है. Android सिस्टम, ऐनिमेशन को एक साथ AnimatorSet में बंडल करने की सुविधा देता है. इससे यह तय किया जा सकता है कि ऐनिमेशन एक साथ शुरू हों, क्रम से शुरू हों या तय समय के बाद शुरू हों. AnimatorSet ऑब्जेक्ट को एक-दूसरे में नेस्ट भी किया जा सकता है.

नीचे दिया गया कोड स्निपेट, Animator ऑब्जेक्ट को इस तरह से चलाता है:

  1. bounceAnim को चलाता है.
  2. squashAnim1, squashAnim2, stretchAnim1, और stretchAnim2 को एक साथ चलाता है.
  3. bounceBackAnim को चलाता है.
  4. fadeAnim को चलाता है.

Kotlin

val bouncer = AnimatorSet().apply {
    play(bounceAnim).before(squashAnim1)
    play(squashAnim1).with(squashAnim2)
    play(squashAnim1).with(stretchAnim1)
    play(squashAnim1).with(stretchAnim2)
    play(bounceBackAnim).after(stretchAnim2)
}
val fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
}
AnimatorSet().apply {
    play(bouncer).before(fadeAnim)
    start()
}

Java

AnimatorSet bouncer = new AnimatorSet();
bouncer.play(bounceAnim).before(squashAnim1);
bouncer.play(squashAnim1).with(squashAnim2);
bouncer.play(squashAnim1).with(stretchAnim1);
bouncer.play(squashAnim1).with(stretchAnim2);
bouncer.play(bounceBackAnim).after(stretchAnim2);
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();

ऐनिमेशन लिसनर

नीचे दिए गए लिसनर की मदद से, ऐनिमेशन के दौरान अहम इवेंट के बारे में सुना जा सकता है.

  • Animator.AnimatorListener
    • onAnimationStart() - यह तब कॉल किया जाता है, जब ऐनिमेशन शुरू होता है.
    • onAnimationEnd() - ऐनिमेशन खत्म होने पर कॉल किया जाता है.
    • onAnimationRepeat() - इस इवेंट को तब कॉल किया जाता है, जब ऐनिमेशन खुद को दोहराता है.
    • onAnimationCancel() - इस फ़ंक्शन को तब कॉल किया जाता है, जब ऐनिमेशन रद्द कर दिया जाता है. रद्द किया गया ऐनिमेशन भी onAnimationEnd() को कॉल करता है. भले ही, उन्हें कैसे भी खत्म किया गया हो.
  • ValueAnimator.AnimatorUpdateListener
    • onAnimationUpdate() - इसे ऐनिमेशन के हर फ़्रेम पर कॉल किया जाता है. इस इवेंट को सुनें, ताकि ऐनिमेशन के दौरान ValueAnimator से जनरेट की गई कैलकुलेट की गई वैल्यू का इस्तेमाल किया जा सके. इस वैल्यू का इस्तेमाल करने के लिए, इवेंट में पास किए गए ValueAnimator ऑब्जेक्ट को क्वेरी करें. इससे आपको getAnimatedValue() तरीके से, ऐनिमेशन की मौजूदा वैल्यू मिलेगी. अगर ValueAnimator का इस्तेमाल किया जाता है, तो इस लिसनर को लागू करना ज़रूरी है.

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

अगर आपको Animator.AnimatorListener इंटरफ़ेस के सभी तरीकों को लागू नहीं करना है, तो Animator.AnimatorListener इंटरफ़ेस को लागू करने के बजाय, AnimatorListenerAdapter क्लास को एक्सटेंड किया जा सकता है. AnimatorListenerAdapter क्लास, उन तरीकों के लिए खाली इम्प्लीमेंटेशन उपलब्ध कराती है जिन्हें बदला जा सकता है.

उदाहरण के लिए, यहां दिया गया कोड स्निपेट सिर्फ़ onAnimationEnd() कॉलबैक के लिए AnimatorListenerAdapter बनाता है:

Kotlin

ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            balls.remove((animation as ObjectAnimator).target)
        }
    })
}

Java

ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
    balls.remove(((ObjectAnimator)animation).getTarget());
}

ViewGroup ऑब्जेक्ट के लेआउट में हुए बदलावों को ऐनिमेट करना

प्रॉपर्टी ऐनिमेशन सिस्टम की मदद से, ViewGroup ऑब्जेक्ट में हुए बदलावों को ऐनिमेट किया जा सकता है. साथ ही, View ऑब्जेक्ट को आसानी से ऐनिमेट किया जा सकता है.

LayoutTransition क्लास की मदद से, ViewGroup में लेआउट में हुए बदलावों को ऐनिमेट किया जा सकता है. जब किसी ViewGroup में व्यू जोड़े या हटाए जाते हैं या जब View के setVisibility() तरीके को VISIBLE, INVISIBLE या GONE के साथ कॉल किया जाता है, तब ViewGroup में मौजूद व्यू दिखने और गायब होने वाले ऐनिमेशन से गुज़र सकते हैं. व्यू जोड़ने या हटाने पर, ViewGroup में मौजूद बाकी व्यू भी अपनी नई जगहों पर ऐनिमेट हो सकते हैं. LayoutTransition ऑब्जेक्ट में, यहां दिए गए ऐनिमेशन तय किए जा सकते हैं. इसके लिए, setAnimator() को कॉल करें और यहां दिए गए LayoutTransition कॉन्स्टेंट में से किसी एक के साथ Animator ऑब्जेक्ट पास करें:

  • APPEARING - यह एक फ़्लैग है. इससे पता चलता है कि कंटेनर में दिखने वाले आइटम पर कौन-सा ऐनिमेशन चल रहा है.
  • CHANGE_APPEARING - यह एक फ़्लैग है. यह उन आइटम पर चलने वाले ऐनिमेशन के बारे में बताता है जिनमें कंटेनर में नया आइटम दिखने की वजह से बदलाव हो रहा है.
  • DISAPPEARING - यह एक फ़्लैग है. इससे उस ऐनिमेशन के बारे में पता चलता है जो कंटेनर से गायब हो रहे आइटम पर चलता है.
  • CHANGE_DISAPPEARING - यह एक फ़्लैग है. इससे उस ऐनिमेशन के बारे में पता चलता है जो उन आइटम पर चलता है जिनमें कंटेनर से आइटम गायब होने की वजह से बदलाव हो रहा है.

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

ViewGroup के लिए, android:animateLayoutchanges एट्रिब्यूट को true पर सेट करने के लिए, यह तरीका अपनाएं:

<LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/verticalContainer"
    android:animateLayoutChanges="true" />

इस एट्रिब्यूट को सही पर सेट करने से, ViewGroup में जोड़ी या हटाई गई Views के साथ-साथ ViewGroup में मौजूद बाकी Views भी अपने-आप ऐनिमेट हो जाती हैं.

StateListAnimator का इस्तेमाल करके, व्यू की स्थिति में हुए बदलावों को ऐनिमेट करना

StateListAnimator क्लास की मदद से, ऐसे ऐनिमेटर तय किए जा सकते हैं जो व्यू की स्थिति बदलने पर चलते हैं. यह ऑब्जेक्ट, Animator ऑब्जेक्ट के लिए रैपर के तौर पर काम करता है. यह ऑब्जेक्ट, तय की गई व्यू की स्थिति (जैसे, "दबाया गया" या "फ़ोकस किया गया") में बदलाव होने पर, उस ऐनिमेशन को कॉल करता है.

StateListAnimator को XML रिसॉर्स में तय किया जा सकता है. इसके लिए, रूट <selector> एलिमेंट और चाइल्ड <item> एलिमेंट का इस्तेमाल किया जाता है. हर चाइल्ड एलिमेंट, StateListAnimator क्लास से तय की गई अलग-अलग व्यू स्टेट के बारे में बताता है. हर <item> में, प्रॉपर्टी ऐनिमेशन सेट की परिभाषा शामिल होती है.

उदाहरण के लिए, यहां दी गई फ़ाइल एक स्टेट लिस्ट ऐनिमेटर बनाती है. जब व्यू को दबाया जाता है, तब यह व्यू के x और y स्केल को बदलता है:

res/xml/animate_scale.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- the pressed state; increase x and y size to 150% -->
    <item android:state_pressed="true">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
        </set>
    </item>
    <!-- the default, non-pressed state; set x and y size to 100% -->
    <item android:state_pressed="false">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
        </set>
    </item>
</selector>

स्टेट लिस्ट ऐनिमेटर को किसी व्यू से अटैच करने के लिए, android:stateListAnimator एट्रिब्यूट को इस तरह जोड़ें:

<Button android:stateListAnimator="@xml/animate_scale"
        ... />

अब इस बटन की स्थिति बदलने पर, animate_scale.xml में तय की गई ऐनिमेशन का इस्तेमाल किया जाता है.

इसके अलावा, अपने कोड में किसी व्यू को स्टेट लिस्ट ऐनिमेटर असाइन करने के लिए, AnimatorInflater.loadStateListAnimator() तरीके का इस्तेमाल करें. इसके बाद, View.setStateListAnimator() तरीके का इस्तेमाल करके, ऐनिमेटर को अपने व्यू पर असाइन करें.

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

<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- provide a different drawable for each state-->
    <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
        android:state_pressed="true"/>
    <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
        android:state_focused="true"/>
    <item android:id="@id/default"
        android:drawable="@drawable/drawableD"/>

    <!-- specify a transition -->
    <transition android:fromId="@+id/default" android:toId="@+id/pressed">
        <animation-list>
            <item android:duration="15" android:drawable="@drawable/dt1"/>
            <item android:duration="15" android:drawable="@drawable/dt2"/>
            ...
        </animation-list>
    </transition>
    ...
</animated-selector>

TypeEvaluator का इस्तेमाल करना

अगर आपको Android सिस्टम के लिए अज्ञात टाइप को ऐनिमेट करना है, तो TypeEvaluator इंटरफ़ेस लागू करके अपना खुद का इवैल्यूएटर बनाया जा सकता है. Android सिस्टम को int, float या रंग के बारे में पता होता है. ये IntEvaluator, FloatEvaluator, और ArgbEvaluator टाइप के वैल्यू एस्टीमेटर के साथ काम करते हैं.

TypeEvaluator इंटरफ़ेस में, evaluate() तरीके का इस्तेमाल करके ही कन्वर्ज़न ट्रैकिंग लागू की जा सकती है. इससे ऐनिमेटर को, ऐनिमेशन के मौजूदा पॉइंट पर आपकी ऐनिमेट की गई प्रॉपर्टी के लिए सही वैल्यू मिलती है. FloatEvaluator क्लास में, ऐसा करने का तरीका बताया गया है:

Kotlin

private class FloatEvaluator : TypeEvaluator<Any> {

    override fun evaluate(fraction: Float, startValue: Any, endValue: Any): Any {
        return (startValue as Number).toFloat().let { startFloat ->
            startFloat + fraction * ((endValue as Number).toFloat() - startFloat)
        }
    }

}

Java

public class FloatEvaluator implements TypeEvaluator {

    public Object evaluate(float fraction, Object startValue, Object endValue) {
        float startFloat = ((Number) startValue).floatValue();
        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
    }
}

ध्यान दें: जब ValueAnimator (या ObjectAnimator) चलता है, तो यह एनिमेशन के मौजूदा समय का हिसाब लगाता है. यह वैल्यू 0 और 1 के बीच होती है. इसके बाद, यह उस वैल्यू का इंटरपोलेटेड वर्शन का हिसाब लगाता है. यह इस बात पर निर्भर करता है कि कौनसे इंटरपोलेटर का इस्तेमाल किया जा रहा है. इंटरपोलेट किया गया फ़्रैक्शन, fraction पैरामीटर के ज़रिए TypeEvaluator को मिलता है. इसलिए, ऐनिमेशन वाली वैल्यू का हिसाब लगाते समय, आपको इंटरपोलेटर को ध्यान में रखने की ज़रूरत नहीं है.

इंटरपोलेटर का इस्तेमाल करना

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

ऐनिमेशन सिस्टम में इंटरपोलेटर को ऐनिमेटर से एक फ़्रैक्शन मिलता है. यह फ़्रैक्शन, ऐनिमेशन के गुज़रे हुए समय को दिखाता है. इंटरपोलेटर, इस फ़्रैक्शन में बदलाव करते हैं, ताकि यह उस तरह के ऐनिमेशन से मेल खाए जिसे उन्हें दिखाना है. Android सिस्टम, android.view.animation package में इंटरपोलेटर का एक सामान्य सेट उपलब्ध कराता है. अगर इनमें से कोई भी आपकी ज़रूरतों के मुताबिक नहीं है, तो TimeInterpolator इंटरफ़ेस लागू किया जा सकता है. साथ ही, अपने हिसाब से इंटरफ़ेस बनाया जा सकता है.

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

AccelerateDecelerateInterpolator

Kotlin

override fun getInterpolation(input: Float): Float =
        (Math.cos((input + 1) * Math.PI) / 2.0f).toFloat() + 0.5f

Java

@Override
public float getInterpolation(float input) {
    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}

LinearInterpolator

Kotlin

override fun getInterpolation(input: Float): Float = input

Java

@Override
public float getInterpolation(float input) {
    return input;
}

यहां दी गई टेबल में, 1,000 मि॰से॰ तक चलने वाले ऐनिमेशन के लिए, इन इंटरपोलेटर से कैलकुलेट की गई अनुमानित वैल्यू दिखाई गई हैं:

ms elapsed बीता हुआ फ़्रैक्शन/इंटरपोलेट किया गया फ़्रैक्शन (लीनियर) इंटरपोलेटेड फ़्रैक्शन (तेज़/धीमा करें)
0 0 0
200 .2 .1
400 .4 .345
600 .6 .654
800 .8 .9
1000 1 1

टेबल में दिखाया गया है कि LinearInterpolator, वैल्यू को एक ही स्पीड से बदलता है. हर 200 मि॰से॰ के लिए, वैल्यू में 0.2 का बदलाव होता है. AccelerateDecelerateInterpolator, 200 मि॰से॰ से 600 मि॰से॰ के बीच LinearInterpolator की तुलना में वैल्यू को ज़्यादा तेज़ी से बदलता है. वहीं, 600 मि॰से॰ से 1000 मि॰से॰ के बीच वैल्यू को ज़्यादा धीरे-धीरे बदलता है.

मुख्य फ़्रेम तय करना

Keyframe ऑब्जेक्ट में समय/वैल्यू पेयर होता है. इससे ऐनिमेशन के किसी खास समय पर, कोई खास स्थिति तय की जा सकती है. हर कीफ़्रेम का अपना इंटरपोलेटर भी हो सकता है. इससे पिछले कीफ़्रेम के समय और इस कीफ़्रेम के समय के बीच के इंटरवल में ऐनिमेशन के व्यवहार को कंट्रोल किया जा सकता है.

Keyframe ऑब्जेक्ट को इंस्टैंटिएट करने के लिए, आपको फ़ैक्ट्री के किसी एक तरीके का इस्तेमाल करना होगा. जैसे, ofInt(), ofFloat() या ofObject(). इससे आपको सही तरह का Keyframe मिलेगा. इसके बाद, PropertyValuesHolder ऑब्जेक्ट पाने के लिए, ofKeyframe() फ़ैक्ट्री मेथड को कॉल करें. ऑब्जेक्ट मिलने के बाद, PropertyValuesHolder ऑब्जेक्ट और ऐनिमेट किए जाने वाले ऑब्जेक्ट को पास करके, ऐनिमेटर पाया जा सकता है. नीचे दिए गए कोड स्निपेट में, ऐसा करने का तरीका बताया गया है:

Kotlin

val kf0 = Keyframe.ofFloat(0f, 0f)
val kf1 = Keyframe.ofFloat(.5f, 360f)
val kf2 = Keyframe.ofFloat(1f, 0f)
val pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2)
ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation).apply {
    duration = 5000
}

Java

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation);
rotationAnim.setDuration(5000);

व्यू को ऐनिमेट करना

प्रॉपर्टी ऐनिमेशन सिस्टम, व्यू ऑब्जेक्ट के ऐनिमेशन को आसान बनाता है. साथ ही, यह व्यू ऐनिमेशन सिस्टम की तुलना में कुछ फ़ायदे देता है. व्यू ऐनिमेशन सिस्टम, व्यू ऑब्जेक्ट को इस तरह से बदलता है कि उन्हें अलग तरीके से बनाया जाता है. इसे हर व्यू के कंटेनर में हैंडल किया गया था, क्योंकि व्यू में बदलाव करने के लिए कोई प्रॉपर्टी नहीं थी. इससे व्यू ऐनिमेट हो गया, लेकिन व्यू ऑब्जेक्ट में कोई बदलाव नहीं हुआ. इस वजह से, ऑब्जेक्ट अपनी मूल जगह पर ही मौजूद रहता था. भले ही, उसे स्क्रीन पर किसी दूसरी जगह पर बनाया गया हो. Android 3.0 में, नई प्रॉपर्टी और उनसे जुड़े getter और setter तरीके जोड़े गए, ताकि इस कमी को दूर किया जा सके.

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

  • translationX और translationY: इन प्रॉपर्टी से यह कंट्रोल किया जाता है कि व्यू, अपने बाएं और ऊपर के कोऑर्डिनेट से कितनी दूरी पर है. ये कोऑर्डिनेट, लेआउट कंटेनर सेट करता है.
  • rotation, rotationX, और rotationY: ये प्रॉपर्टी, पिवट पॉइंट के चारों ओर 2D (rotation प्रॉपर्टी) और 3D में रोटेशन को कंट्रोल करती हैं.
  • scaleX और scaleY: ये प्रॉपर्टी, किसी व्यू के पिवट पॉइंट के आस-पास उसकी 2D स्केलिंग को कंट्रोल करती हैं.
  • pivotX और pivotY: ये प्रॉपर्टी, पिवट पॉइंट की जगह को कंट्रोल करती हैं. पिवट पॉइंट के चारों ओर रोटेशन और स्केलिंग ट्रांसफ़ॉर्म होते हैं. डिफ़ॉल्ट रूप से, पिवट पॉइंट ऑब्जेक्ट के बीच में होता है.
  • x और y: ये सामान्य यूटिलिटी प्रॉपर्टी हैं. इनका इस्तेमाल, व्यू की कंटेनर में मौजूद फ़ाइनल जगह के बारे में बताने के लिए किया जाता है. यह जगह, बाईं ओर और ऊपर की वैल्यू के साथ-साथ translationX और translationY वैल्यू के योग के तौर पर तय की जाती है.
  • alpha: इससे व्यू पर ऐल्फ़ा ट्रांसपेरेंसी के बारे में पता चलता है. डिफ़ॉल्ट रूप से, इस वैल्यू को 1 (ओपेक) पर सेट किया जाता है. वहीं, 0 वैल्यू का मतलब है कि पूरी तरह से पारदर्शी (दिखाई नहीं देता).

किसी व्यू ऑब्जेक्ट की प्रॉपर्टी को ऐनिमेट करने के लिए, जैसे कि उसका रंग या रोटेशन वैल्यू, आपको बस एक प्रॉपर्टी ऐनिमेटर बनाना होता है. इसके बाद, उस व्यू प्रॉपर्टी के बारे में बताना होता है जिसे आपको ऐनिमेट करना है. उदाहरण के लिए:

Kotlin

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f)

Java

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

ऐनिमेटर बनाने के बारे में ज़्यादा जानने के लिए, ValueAnimator और ObjectAnimator की मदद से ऐनिमेशन बनाने से जुड़े सेक्शन देखें.

ViewPropertyAnimator का इस्तेमाल करके ऐनिमेट करना

ViewPropertyAnimator की मदद से, View की कई प्रॉपर्टी को एक साथ ऐनिमेट किया जा सकता है. इसके लिए, सिर्फ़ एक Animator ऑब्जेक्ट का इस्तेमाल किया जाता है. यह ObjectAnimator की तरह काम करता है, क्योंकि यह व्यू की प्रॉपर्टी की असल वैल्यू में बदलाव करता है. हालांकि, एक साथ कई प्रॉपर्टी को ऐनिमेट करने के लिए, यह ज़्यादा बेहतर है. इसके अलावा, ViewPropertyAnimator का इस्तेमाल करने के लिए कोड बहुत छोटा है और इसे पढ़ना आसान है. नीचे दिए गए कोड स्निपेट में, एक साथ किसी व्यू की x और y प्रॉपर्टी को ऐनिमेट करते समय, एक से ज़्यादा ObjectAnimator ऑब्जेक्ट, एक ObjectAnimator, और ViewPropertyAnimator का इस्तेमाल करने के बीच के अंतर को दिखाया गया है.

कई ObjectAnimator ऑब्जेक्ट

Kotlin

val animX = ObjectAnimator.ofFloat(myView, "x", 50f)
val animY = ObjectAnimator.ofFloat(myView, "y", 100f)
AnimatorSet().apply {
    playTogether(animX, animY)
    start()
}

Java

ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();

One ObjectAnimator

Kotlin

val pvhX = PropertyValuesHolder.ofFloat("x", 50f)
val pvhY = PropertyValuesHolder.ofFloat("y", 100f)
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start()

Java

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();

ViewPropertyAnimator

Kotlin

myView.animate().x(50f).y(100f)

Java

myView.animate().x(50f).y(100f);

ViewPropertyAnimator के बारे में ज़्यादा जानकारी के लिए, Android Developers की ब्लॉग पोस्ट पढ़ें.

XML में ऐनिमेशन के बारे में जानकारी देना

प्रॉपर्टी ऐनिमेशन सिस्टम की मदद से, प्रॉपर्टी ऐनिमेशन को प्रोग्राम के हिसाब से सेट करने के बजाय, एक्सएमएल की मदद से सेट किया जा सकता है. एक्सएमएल में ऐनिमेशन तय करने से, उन्हें कई गतिविधियों में आसानी से फिर से इस्तेमाल किया जा सकता है. साथ ही, ऐनिमेशन के क्रम में आसानी से बदलाव किया जा सकता है.

नई प्रॉपर्टी ऐनिमेशन एपीआई का इस्तेमाल करने वाली ऐनिमेशन फ़ाइलों को, लेगसी व्यू ऐनिमेशन फ़्रेमवर्क का इस्तेमाल करने वाली फ़ाइलों से अलग करने के लिए, Android 3.1 से प्रॉपर्टी ऐनिमेशन के लिए एक्सएमएल फ़ाइलों को res/animator/ डायरेक्ट्री में सेव करना चाहिए.

प्रॉपर्टी ऐनिमेशन की इन क्लास के लिए, एक्सएमएल डिक्लेरेशन की सुविधा उपलब्ध है. इसके लिए, इन एक्सएमएल टैग का इस्तेमाल किया जाता है:

एक्सएमएल डिक्लेरेशन में इस्तेमाल किए जा सकने वाले एट्रिब्यूट ढूंढने के लिए, ऐनिमेशन संसाधन देखें. इस उदाहरण में, ऑब्जेक्ट ऐनिमेशन के दो सेट को क्रम से चलाया जाता है. पहले नेस्ट किए गए सेट में, ऑब्जेक्ट ऐनिमेशन के दो सेट एक साथ चलते हैं:

<set android:ordering="sequentially">
    <set>
        <objectAnimator
            android:propertyName="x"
            android:duration="500"
            android:valueTo="400"
            android:valueType="intType"/>
        <objectAnimator
            android:propertyName="y"
            android:duration="500"
            android:valueTo="300"
            android:valueType="intType"/>
    </set>
    <objectAnimator
        android:propertyName="alpha"
        android:duration="500"
        android:valueTo="1f"/>
</set>

इस ऐनिमेशन को चलाने के लिए, आपको अपने कोड में मौजूद XML संसाधनों को AnimatorSet ऑब्जेक्ट में बढ़ाना होगा. इसके बाद, ऐनिमेशन सेट शुरू करने से पहले, सभी ऐनिमेशन के लिए टारगेट ऑब्जेक्ट सेट करने होंगे. setTarget() को कॉल करने पर, AnimatorSet के सभी चाइल्ड ऑब्जेक्ट के लिए एक ही टारगेट ऑब्जेक्ट सेट हो जाता है. इस काम को करने का तरीका यहां दिया गया है:

Kotlin

(AnimatorInflater.loadAnimator(myContext, R.animator.property_animator) as AnimatorSet).apply {
    setTarget(myObject)
    start()
}

Java

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
    R.animator.property_animator);
set.setTarget(myObject);
set.start();

एक्सएमएल में भी ValueAnimator का एलान किया जा सकता है. इसका उदाहरण यहां दिया गया है:

<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:valueType="floatType"
    android:valueFrom="0f"
    android:valueTo="-100f" />

अपने कोड में पिछले ValueAnimator का इस्तेमाल करने के लिए, आपको ऑब्जेक्ट को बड़ा करना होगा, AnimatorUpdateListener जोड़ना होगा, अपडेट की गई ऐनिमेशन वैल्यू हासिल करनी होगी, और उसे अपने किसी व्यू की प्रॉपर्टी में इस्तेमाल करना होगा. इसके लिए, यहां दिया गया कोड देखें:

Kotlin

(AnimatorInflater.loadAnimator(this, R.animator.animator) as ValueAnimator).apply {
    addUpdateListener { updatedAnimation ->
        textView.translationX = updatedAnimation.animatedValue as Float
    }

    start()
}

Java

ValueAnimator xmlAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this,
        R.animator.animator);
xmlAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

xmlAnimator.start();

प्रॉपर्टी के ऐनिमेशन तय करने के लिए, एक्सएमएल सिंटैक्स के बारे में जानकारी पाने के लिए, ऐनिमेशन रिसॉर्स देखें.

यूज़र इंटरफ़ेस (यूआई) की परफ़ॉर्मेंस पर संभावित असर

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

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