पिछले कुछ वर्षों में, हमने Android एप्लिकेशन बनाने के लिए सामान्य दृष्टिकोण विकसित किए हैं। शुद्ध वास्तुकला, वास्तुशिल्प पैटर्न (एमवीसी, एमवीपी, एमवीवीएम, एमवीआई), रिपॉजिटरी पैटर्न और अन्य। हालाँकि, अनुप्रयोग के भीतर नेविगेशन को व्यवस्थित करने के लिए अभी भी आम तौर पर स्वीकृत दृष्टिकोण नहीं हैं। आज मैं आपसे "समन्वयक" टेम्पलेट और एंड्रॉइड एप्लिकेशन के विकास में इसके आवेदन की संभावनाओं के बारे में बात करना चाहता हूं।
समन्वयक पैटर्न का उपयोग अक्सर आईओएस अनुप्रयोगों में किया जाता है और इसे सोरूस खान्लू द्वारा पेश किया गया था ताकि एप्लिकेशन के नेविगेशन को सरल बनाया जा सके। यह माना जाता है कि सोरुष का काम मार्टिन फॉवलर द्वारा एंटरप्राइज एप्लिकेशन आर्किटेक्चर के पैटर्न में वर्णित एप्लिकेशन कंट्रोलर दृष्टिकोण पर आधारित है।
"समन्वयक" टेम्पलेट निम्नलिखित कार्यों को हल करने के लिए डिज़ाइन किया गया है:
- मैसिव व्यू कंट्रोलर समस्या के साथ संघर्ष (समस्या पहले से ही हब - अनुवादक के नोट पर लिखी गई थी), जो अक्सर ईश्वर-गतिविधि (बहुत सारी जिम्मेदारियों के साथ गतिविधि) के आगमन के साथ प्रकट होती है।
- एक अलग इकाई में नेविगेशन तर्क का पृथक्करण
- नेविगेशन तर्क के साथ कमजोर संबंध के कारण एप्लिकेशन स्क्रीन (गतिविधि / टुकड़े) का पुन: उपयोग
लेकिन, इससे पहले कि आप खुद को टेम्पलेट से परिचित करना शुरू करें और इसे लागू करने का प्रयास करें, आइए एंड्रॉइड एप्लिकेशन में उपयोग किए जाने वाले नेविगेशन कार्यान्वयन पर एक नज़र डालें।
नेविगेशन तर्क गतिविधि / टुकड़े में वर्णित है
चूंकि एंड्रॉइड एसडीके को एक नई गतिविधि (या फ्रैगमेंट मैनजर को गतिविधि में एक टुकड़ा जोड़ने के लिए) खोलने के लिए संदर्भ की आवश्यकता होती है, अक्सर नेविगेशन तर्क को गतिविधि / टुकड़े में सीधे वर्णित किया जाता है। यहां तक कि एंड्रॉइड एसडीके के लिए प्रलेखन में उदाहरण इस दृष्टिकोण का उपयोग करते हैं।
class ShoppingCartActivity : Activity() { override fun onCreate(b : Bundle?){ super.onCreate(b) setContentView(R.layout.activity_shopping_cart) val checkoutButton = findViewById(R.id.checkoutButton) checkoutButton.setOnClickListener { val intent = Intent(this, CheckoutActivity::class.java) startActivity(intent) } } }
उपरोक्त उदाहरण में, नेविगेशन गतिविधि से निकटता से संबंधित है। क्या ऐसे कोड का परीक्षण करना सुविधाजनक है? एक तर्क दे सकता है कि हम नेविगेशन को एक अलग इकाई में अलग कर सकते हैं और इसे नाम दे सकते हैं, उदाहरण के लिए, नेविगेटर, जिसे लागू किया जा सकता है। आइए देखें:
class ShoppingCartActivity : Activity() { @Inject lateinit var navigator : Navigator override fun onCreate(b : Bundle?){ super.onCreate(b) setContentView(R.layout.activity_shopping_cart) val checkoutButton = findViewById(R.id.checkoutButton) checkoutButton.setOnClickListener { navigator.showCheckout(this) } } } class Navigator { fun showCheckout(activity : Activity){ val intent = Intent(activity, CheckoutActivity::class.java) activity.startActivity(intent) } }
यह बुरा नहीं निकला, लेकिन मैं और अधिक चाहता हूं।
MVVM / MVP के साथ नेविगेशन
मैं प्रश्न के साथ शुरू करूँगा: आप MVVM / MVP का उपयोग करते समय नेविगेशन तर्क को कहाँ रखेंगे?
प्रस्तुतकर्ता के तहत परत में (इसे व्यापार तर्क कहते हैं)? एक अच्छा विचार नहीं है, क्योंकि सबसे अधिक संभावना है कि आप अन्य प्रस्तुति मॉडल या प्रस्तुतकर्ताओं में अपने व्यापार तर्क का पुन: उपयोग करेंगे।
दृश्य परत में? क्या आप वाकई प्रस्तुति और प्रस्तुतकर्ता / प्रस्तुति मॉडल के बीच की घटनाओं को फेंकना चाहते हैं? आइए एक उदाहरण देखें:
class ShoppingCartActivity : ShoppingCartView, Activity() { @Inject lateinit var navigator : Navigator @Inject lateinit var presenter : ShoppingCartPresenter override fun onCreate(b : Bundle?){ super.onCreate(b) setContentView(R.layout.activity_shopping_cart) val checkoutButton = findViewById(R.id.checkoutButton) checkoutButton.setOnClickListener { presenter.checkoutClicked() } } override fun navigateToCheckout(){ navigator.showCheckout(this) } } class ShoppingCartPresenter : Presenter<ShoppingCartView> { ... override fun checkoutClicked(){ view?.navigateToCheckout(this) } }
या यदि आप MVVM पसंद करते हैं, तो आप SingleLiveEvents या EventObserver का उपयोग कर सकते हैं
class ShoppingCartActivity : ShoppingCartView, Activity() { @Inject lateinit var navigator : Navigator @Inject lateinit var viewModel : ViewModel override fun onCreate(b : Bundle?){ super.onCreate(b) setContentView(R.layout.activity_shopping_cart) val checkoutButton = findViewById(R.id.checkoutButton) checkoutButton.setOnClickListener { viewModel.checkoutClicked() } viewModel.navigateToCheckout.observe(this, Observer { navigator.showCheckout(this) }) } } class ShoppingCartViewModel : ViewModel() { val navigateToCheckout = MutableLiveData<Event<Unit>> fun checkoutClicked(){ navigateToCheckout.value = Event(Unit)
या आइए EventObserver का उपयोग करने के बजाय एक नाविक को एक दृश्य मॉडल में रखें, जैसा कि पिछले उदाहरण में दिखाया गया है
class ShoppingCartViewModel @Inject constructor(val navigator : Navigator) : ViewModel() }
कृपया ध्यान दें कि यह दृष्टिकोण प्रस्तुतकर्ता पर लागू किया जा सकता है। अगर यह एक्टीवेटर का लिंक रखता है तो हम नेविगेटर में एक संभावित मेमोरी लीक को भी अनदेखा कर देते हैं।
समन्वयक
तो हम नेविगेशन लॉजिक को कहां रखें? व्यापार तर्क? हमने पहले ही इस विकल्प पर विचार किया है और इस निष्कर्ष पर पहुंचे हैं कि यह सबसे अच्छा समाधान नहीं है। दृश्य और दृश्य मॉडल के बीच की घटनाओं को फेंकना काम कर सकता है, लेकिन यह एक सुरुचिपूर्ण समाधान की तरह नहीं दिखता है। इसके अलावा, दृश्य अभी भी नेविगेशन तर्क के लिए जिम्मेदार है, भले ही हम इसे नाविक के पास ले आए। बहिष्करण की पद्धति के बाद, हमारे पास अभी भी प्रस्तुति मॉडल में नेविगेशन तर्क रखने का विकल्प है, और यह विकल्प आशाजनक लगता है। लेकिन क्या दृश्य मॉडल को नेविगेशन के बारे में ध्यान रखना चाहिए? क्या यह दृश्य और मॉडल के बीच की एक परत नहीं है? इसलिए हम एक समन्वयक की धारणा में आए।
"हमें अमूर्तता के एक और स्तर की आवश्यकता क्यों है?" - आप पूछें। क्या यह प्रणाली की जटिलता के लायक है? छोटी परियोजनाओं में, अमूर्तता के लिए अमूर्तता वास्तव में बदल सकती है, लेकिन जटिल अनुप्रयोगों में या ए / बी परीक्षणों का उपयोग करने के मामले में, समन्वयक उपयोगी हो सकता है। मान लीजिए कि कोई उपयोगकर्ता खाता बना सकता है और लॉग इन कर सकता है। हमारे पास पहले से ही कुछ तर्क हैं, जहां हमें यह जांचना होगा कि क्या उपयोगकर्ता ने लॉगिन किया है या तो लॉगिन स्क्रीन या एप्लिकेशन की मुख्य स्क्रीन दिखाएगा। समन्वयक दिए गए उदाहरण के साथ मदद कर सकता है। ध्यान दें कि समन्वयक कम कोड लिखने में मदद नहीं करता है, यह दृश्य या दृश्य मॉडल से नेविगेशन तर्क का कोड प्राप्त करने में मदद करता है।
समन्वयक का विचार अत्यंत सरल है। वह केवल यह जानता है कि आगे कौन सी एप्लिकेशन स्क्रीन खोलनी है। उदाहरण के लिए, जब कोई उपयोगकर्ता किसी ऑर्डर के लिए भुगतान बटन पर क्लिक करता है, तो समन्वयक को संबंधित घटना प्राप्त होती है और यह पता चलता है कि अगला चरण भुगतान स्क्रीन खोलने का है। IOS में, समन्वयक को ViewControllers बनाने और बैक स्टैक को नियंत्रित करने के लिए एक सेवा लोकेटर के रूप में उपयोग किया जाता है। यह समन्वयक के लिए पर्याप्त है (एकमात्र जिम्मेदारी के सिद्धांत को याद रखें)। एंड्रॉइड एप्लिकेशन में, सिस्टम एक्टिविटीज बनाता है, हमारे पास निर्भरता को लागू करने के लिए कई उपकरण हैं और एक्टिविटीज और टुकड़े के लिए बैकस्टैक है। अब आइए समन्वयक के मूल विचार पर वापस आते हैं: समन्वयक सिर्फ यह जानता है कि आगे कौन सी स्क्रीन होगी।
उदाहरण: एक समन्वयक का उपयोग करके समाचार अनुप्रयोग
चलो अंत में सीधे टेम्पलेट के बारे में बात करते हैं। कल्पना कीजिए कि हमें एक साधारण समाचार एप्लिकेशन बनाने की आवश्यकता है। एप्लिकेशन में 2 स्क्रीन हैं: "लेखों की सूची" और "लेख पाठ", जो एक सूची आइटम पर क्लिक करके खोला जाता है।

class NewsFlowCoordinator (val navigator : Navigator) { fun start(){ navigator.showNewsList() } fun readNewsArticle(id : Int){ navigator.showNewsArticle(id) } }
एक स्क्रिप्ट (फ्लो) में एक या अधिक स्क्रीन होती हैं। हमारे उदाहरण में, समाचार परिदृश्य में 2 स्क्रीन होते हैं: "लेख सूची" और "लेख पाठ"। समन्वयक बेहद सरल थे। जब आवेदन शुरू होता है, तो हम लेखों की सूची प्रदर्शित करने के लिए NewsFlowCoordinator # start () कहते हैं। जब कोई उपयोगकर्ता किसी सूची आइटम पर क्लिक करता है, तो NewsFlowCoordinator # readNewsArticle (id) विधि कहा जाता है और लेख के पूर्ण पाठ के साथ एक स्क्रीन प्रदर्शित की जाती है। हम अभी भी नाविक के साथ काम कर रहे हैं (हम इसके बारे में थोड़ी देर बाद बात करेंगे), जिसके लिए हम स्क्रीन के उद्घाटन को देखते हैं। समन्वयक के पास कोई राज्य नहीं है, यह बैक-एंड के कार्यान्वयन पर निर्भर नहीं करता है और केवल एक फ़ंक्शन को लागू करता है: यह निर्धारित करता है कि आगे कहां जाना है।
लेकिन समन्वयक को हमारी प्रस्तुति मॉडल से कैसे जोड़ा जाए? हम निर्भरता व्युत्क्रम के सिद्धांत का पालन करेंगे: हम लैम्बडा को व्यू मॉडल में पारित करेंगे, जिसे उपयोगकर्ता द्वारा लेख पर टैप करने पर कहा जाएगा।
class NewsListViewModel( newsRepository : NewsRepository, var onNewsItemClicked: ( (Int) -> Unit )? ) : ViewModel() { val newsArticles = MutableLiveData<List<News>> private val disposable = newsRepository.getNewsArticles().subscribe { newsArticles.value = it } fun newsArticleClicked(id : Int){ onNewsItemClicked!!(id)
onNewsItemClicked: (Int) -> यूनिट एक लैम्ब्डा है जिसमें एक पूर्णांक तर्क और रिटर्न यूनिट है। कृपया ध्यान दें कि लैम्ब्डा अशक्त हो सकता है, यह हमें स्मृति रिसाव से बचने के लिए लिंक को साफ़ करने की अनुमति देगा। व्यू मॉडल के निर्माता (उदाहरण के लिए, एक डैगर) को समन्वयक पद्धति का लिंक पास करना होगा:
return NewsListViewModel( newsRepository = newsRepository, onNewsItemClicked = newsFlowCoordinator::readNewsArticle )
इससे पहले, हमने नाविक का उल्लेख किया, जो स्क्रीन के परिवर्तन को करता है। नेविगेटर का कार्यान्वयन आपके विवेक पर है, क्योंकि यह आपके विशिष्ट दृष्टिकोण और व्यक्तिगत प्राथमिकताओं पर निर्भर करता है। हमारे उदाहरण में, हम कई टुकड़ों के साथ एक गतिविधि का उपयोग करते हैं (एक स्क्रीन - अपने स्वयं के प्रस्तुति मॉडल के साथ एक टुकड़ा)। मैं एक नाविक का अनुभवहीन कार्यान्वयन देता हूं:
class Navigator{ var activity : FragmentActivity? = null fun showNewsList(){ activty!!.supportFragmentManager .beginTransaction() .replace(R.id.fragmentContainer, NewsListFragment()) .commit() } fun showNewsDetails(newsId: Int) { activty!!.supportFragmentManager .beginTransaction() .replace(R.id.fragmentContainer, NewsDetailFragment.newInstance(newsId)) .addToBackStack("NewsDetail") .commit() } } class MainActivity : AppCompatActivity() { @Inject lateinit var navigator : Navigator override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) navigator.activty = this } override fun onDestroy() { super.onDestroy() navigator.activty = null
नेविगेटर का उपरोक्त कार्यान्वयन आदर्श नहीं है, लेकिन इस पोस्ट का मुख्य विचार एक समन्वयक को पैटर्न में पेश करना है। यह ध्यान देने योग्य है कि चूंकि नाविक और समन्वयक के पास कोई राज्य नहीं है, इसलिए उन्हें आवेदन के भीतर घोषित किया जा सकता है (उदाहरण के लिए, एक खंजर में
सिंगलटन स्कोप) और आवेदन # onCreate () में तत्काल किया जा सकता है।
आइए हमारे आवेदन में प्राधिकरण जोड़ें। हम एक नई लॉगिन स्क्रीन (LoginFragment + LoginViewModel) को परिभाषित करेंगे, सादगी के लिए हम पासवर्ड रिकवरी और पंजीकरण को छोड़ देंगे) और LoginFlowCoordinator। NewsFlowCoordinator में नई कार्यक्षमता क्यों न जोड़ें? हम एक ईश्वर-समन्वयक प्राप्त करना नहीं चाहते हैं जो आवेदन में सभी नेविगेशन के लिए जिम्मेदार होगा? इसके अलावा, प्राधिकरण स्क्रिप्ट समाचार पाठक परिदृश्य पर लागू नहीं होती है, है ना?
class LoginFlowCoordinator( val navigator: Navigator ) { fun start(){ navigator.showLogin() } fun registerNewUser(){ navigator.showRegistration() } fun forgotPassword(){ navigator.showRecoverPassword() } } class LoginViewModel( val usermanager: Usermanager, var onSignUpClicked: ( () -> Unit )?, var onForgotPasswordClicked: ( () -> Unit )? ) { fun login(username : String, password : String){ usermanager.login(username, password) ... } ... }
यहां हम देखते हैं कि प्रत्येक UI ईवेंट के लिए एक संगत लैम्ब्डा है, हालांकि एक सफल लॉगिन के कॉलबैक के लिए लैम्ब्डा नहीं है। यह एक कार्यान्वयन विवरण भी है और आप संबंधित लंबोदर जोड़ सकते हैं, हालांकि मेरे पास एक बेहतर विचार है। आइए एक RootFlowCoordinator जोड़ें और मॉडल परिवर्तनों की सदस्यता लें।
class RootFlowCoordinator( val usermanager: Usermanager, val loginFlowCoordinator: LoginFlowCoordinator, val newsFlowCoordinator: NewsFlowCoordinator, val onboardingFlowCoordinator: OnboardingFlowCoordinator ) { init { usermanager.currentUser.subscribe { user -> when (user){ is NotAuthenticatedUser -> loginFlowCoordinator.start() is AuthenticatedUser -> if (user.onBoardingCompleted) newsFlowCoordinator.start() else onboardingFlowCoordinator.start() } } } fun onboardingCompleted(){ newsFlowCoordinator.start() } }
इस प्रकार, RootFlowCoordinator NewsFlowCoordinator के बजाय हमारे नेविगेशन का प्रवेश बिंदु होगा। आइए RootFlowCoordinator पर ध्यान दें। यदि उपयोगकर्ता लॉग इन है, तो हम जांचते हैं कि क्या उसने ऑनबोर्डिंग पूरी कर ली है (इस पर बाद में) और समाचार या कीबोर्ड के लिए स्क्रिप्ट शुरू करना। कृपया ध्यान दें कि LoginViewModel इस तर्क में शामिल नहीं है। हम ऑनबोर्डिंग परिदृश्य का वर्णन करते हैं।

class OnboardingFlowCoordinator( val navigator: Navigator, val onboardingFinished: () -> Unit // this is RootFlowCoordinator.onboardingCompleted() ) { fun start(){ navigator.showOnboardingWelcome() } fun welcomeShown(){ navigator.showOnboardingPersonalInterestChooser() } fun onboardingCompleted(){ onboardingFinished() } }
Onboarding को OnboardingFlowCoordinator # start () कहकर शुरू किया जाता है, जो WelcomeFragment (WelcomeViewModel) को दर्शाता है। "अगला" बटन पर क्लिक करने के बाद, ऑनबोर्डिंगफ्लोकोऑर्डिनेटर # वेलकमशो () विधि कहा जाता है। जो निम्न स्क्रीन PersonalInterestFragment + PersonalInterestViewModel दिखाता है, जिस पर उपयोगकर्ता दिलचस्प समाचारों की श्रेणियों का चयन करता है। श्रेणियों का चयन करने के बाद, उपयोगकर्ता "अगला" बटन पर टैप करता है और ऑनबोर्डिंगफ्लोकोऑर्डिनेटर # ऑनबोर्डिंगकंप्लीटेड () विधि कहा जाता है, जो रूटफ्लोकोऑर्डिनेटर # ऑनबोर्डिंगकंपनीटेड () को कॉल करता है, जो न्यूजफ्लोकोऑर्डिनेटर लॉन्च करता है।
आइए देखें कि समन्वयक ए / बी परीक्षणों के साथ काम को कैसे सरल बना सकता है। मैं आवेदन में खरीदारी करने की पेशकश के साथ एक स्क्रीन जोड़ूंगा और इसे कुछ उपयोगकर्ताओं को दिखाऊंगा।

class NewsFlowCoordinator ( val navigator : Navigator, val abTest : AbTest ) { fun start(){ navigator.showNewsList() } fun readNewsArticle(id : Int){ navigator.showNewsArticle(id) } fun closeNews(){ if (abTest.isB){ navigator.showInAppPurchases() } else { navigator.closeNews() } } }
फिर, हमने दृश्य या इसके मॉडल में कोई तर्क नहीं जोड़ा है। क्या आपने ऑनबोर्डिंग में InAppPurchaseFragment जोड़ने का फैसला किया है? ऐसा करने के लिए, आपको केवल ऑनबोर्डिंग समन्वयक को बदलने की आवश्यकता है, क्योंकि खरीदारी का टुकड़ा और इसका व्यूमोडल अन्य टुकड़ों से पूरी तरह से स्वतंत्र हैं और हम स्वतंत्र रूप से अन्य परिदृश्यों में इसका पुन: उपयोग कर सकते हैं। समन्वयक ए / बी परीक्षण को लागू करने में भी मदद करेगा, जो दो ऑनबोर्डिंग परिदृश्यों की तुलना करता है।
पूर्ण स्रोत
गितुब पर पाए जा सकते हैं, और आलसी के लिए मैंने एक वीडियो डेमो तैयार किया है
उपयोगी सलाह: कोटलिन का उपयोग करके आप नेविगेशन ग्राफ़ के रूप में समन्वयकों का वर्णन करने के लिए सुविधाजनक डीएसएल बना सकते हैं।
newsFlowCoordinator(navigator, abTest) { start { navigator.showNewsList() } readNewsArticle { id -> navigator.showNewsArticle(id) } closeNews { if (abTest.isB){ navigator.showInAppPurchases() } else { navigator.closeNews() } } }
परिणाम:
समन्वयक परीक्षण किए गए शिथिल युग्मित घटक के लिए नेविगेशन तर्क लाने में मदद करेगा। फिलहाल कोई उत्पादन-तैयार पुस्तकालय नहीं है, मैंने केवल समस्या को हल करने की अवधारणा का वर्णन किया। क्या समन्वयक आपके आवेदन पर लागू होता है? मुझे पता नहीं है, यह आपकी आवश्यकताओं पर निर्भर करता है और मौजूदा वास्तुकला में इसे एकीकृत करना कितना आसान होगा। समन्वयक का उपयोग करके एक छोटा अनुप्रयोग लिखना उपयोगी हो सकता है।
पूछे जाने वाले प्रश्न:
लेख में एमवीआई पैटर्न के साथ एक समन्वयक के उपयोग का उल्लेख नहीं है। क्या इस वास्तुकला के साथ एक समन्वयक का उपयोग करना संभव है? हां, मेरा एक
अलग लेख है ।
Google ने हाल ही में एंड्रॉइड जेटपैक के हिस्से के रूप में नेविगेशन नियंत्रक पेश किया। समन्वयक Google नेविगेशन से कैसे संबंधित है? आप समन्वयक में सीधे नेविगेटर के बजाय नए नेविगेशन नियंत्रक का उपयोग कर सकते हैं या सीधे नेविगेटर में सीधे मैन्युअल रूप से विखंडन लेनदेन बनाने के बजाय कर सकते हैं।
और अगर मैं टुकड़े / गतिविधि का उपयोग नहीं करना चाहता हूं और मैं विचारों को प्रबंधित करने के लिए अपना स्वयं का बैक-एंड लिखना चाहता हूं - तो क्या मैं अपने मामले में समन्वयक का उपयोग कर पाऊंगा? मैंने इस बारे में भी सोचा और एक प्रोटोटाइप पर काम कर रहा हूं। मैं इस बारे में अपने ब्लॉग पर लिखूंगा। मुझे ऐसा लगता है कि राज्य मशीन कार्य को सरल बना देगी।
समन्वयक एकल-गतिविधि-अनुप्रयोग दृष्टिकोण से जुड़ा हुआ है? नहीं, आप इसे विभिन्न परिदृश्यों में उपयोग कर सकते हैं। स्क्रीन के बीच संक्रमण का कार्यान्वयन नेविगेटर में छिपा हुआ है।
वर्णित दृष्टिकोण के साथ, आपको एक विशाल नेविगेटर मिलता है। हम ईश्वर-वस्तु से दूर होने की कोशिश करते हैं? हमें एक कक्षा में नाविक का वर्णन करने की आवश्यकता नहीं है। कई छोटे समर्थित नेविगेटर बनाएं, उदाहरण के लिए, प्रत्येक उपयोगकर्ता परिदृश्य के लिए एक अलग नेविगेटर।
निरंतर संक्रमण एनिमेशन के साथ कैसे काम करें? नेविगेटर में ट्रांस्फ़ॉर्म एनिमेशन का वर्णन करें, फिर गतिविधि / टुकड़े को पिछली / अगली स्क्रीन के बारे में कुछ भी पता नहीं चलेगा। एनीमेशन शुरू करने के लिए नाविक को कैसे पता चलता है? मान लीजिए कि हम टुकड़ों ए और बी के बीच संक्रमण का एक एनीमेशन दिखाना चाहते हैं, हम onFragmentViewCreated (v: View) ईवेंट को FragmentLifecycleCallback का उपयोग करके सब्सक्राइब कर सकते हैं और जब यह घटना होती है तो हम उसी तरह से एनिमेशन के साथ काम कर सकते हैं जैसे हमने सीधे टुकड़े में किया था: OnPreDrawListener जोड़ें तैयार होने तक प्रतीक्षा करें और startPostponedEnterTransition () कॉल करें। लगभग उसी तरीके से, आप एक्टिविटीलिफ़साइकल कॉलबैक का उपयोग करके या व्यूग्रुप के बीच OnHierarchyChangeListener का उपयोग करके गतिविधि के बीच एक एनिमेटेड संक्रमण को लागू कर सकते हैं। मेमोरी लीक से बचने के लिए बाद में घटनाओं से सदस्यता समाप्त करना न भूलें।