چرخه حیات قطعه

هر نمونه Fragment چرخه حیات خودش را دارد. وقتی کاربر در برنامه شما پیمایش و با آن تعامل می‌کند، تکه‌های شما درطول چرخه حیاتشان از حالت‌های مختلفی عبور می‌کنند، زیرا اضافه و حذف می‌شوند و به صفحه وارد یا از آن خارج می‌شوند.

برای مدیریت چرخه حیات، Fragment LifecycleOwner را پیاده‌سازی می‌کند و شیء Lifecycle را درمعرض دید قرار می‌دهد که می‌توانید ازطریق روش getLifecycle() به آن دسترسی داشته باشید.

هر حالت ممکن Lifecycle در Lifecycle.State enum نشان داده می‌شود.

با ساختن Fragment روی Lifecycle، می‌توانید از تکنیک‌ها و کلاس‌های دردسترس برای مدیریت چرخه‌های حیات با مؤلفه‌های آگاه از چرخه حیات استفاده کنید. برای مثال، می‌توانید مکان دستگاه را بااستفاده از مؤلفه آگاه از چرخه حیات روی صفحه‌نمایش نشان دهید. این مؤلفه می‌تواند به‌طور خودکار وقتی قطعه فعال می‌شود شروع به گوش دادن کند و وقتی قطعه به حالت غیرفعال می‌رود، متوقف شود.

به‌عنوان جایگزینی برای استفاده از LifecycleObserver، کلاس Fragment شامل روش‌های فراخوانی است که با هریک از تغییرات در چرخه حیات قطعه مطابقت دارد. این موارد عبارت‌اند از: onCreate()، onStart()، onResume()، onPause()، onStop()، و onDestroy().

نمای قطعه دارای Lifecycle جداگانه‌ای است که به‌طور مستقل از Lifecycle قطعه مدیریت می‌شود. قطعات یک LifecycleOwner برای نمای خود حفظ می‌کنند که بااستفاده از getViewLifecycleOwner() یا getViewLifecycleOwnerLiveData() قابل‌دسترسی است. دسترسی به Lifecycle نما برای موقعیت‌هایی مفید است که مؤلفه آگاه از «چرخه حیات» فقط باید زمانی کار انجام دهد که نمای تکه وجود داشته باشد، مثلاً مشاهده LiveData که فقط برای نمایش در صفحه درنظر گرفته شده است.

این موضوع چرخه حیات Fragment را با جزئیات مورد بحث قرار می‌دهد و برخی از قوانینی را که وضعیت چرخه حیات قطعه را تعیین می‌کنند توضیح می‌دهد و رابطه بین وضعیت‌های Lifecycle و فراخوانی‌های چرخه حیات قطعه را نشان می‌دهد.

قطعه‌ها و مدیر قطعه

وقتی قطعه‌ای نمونه‌سازی می‌شود، در حالت INITIALIZED شروع می‌شود. برای اینکه قطعه‌ای در بقیه چرخه حیاتش انتقال یابد، باید به FragmentManager اضافه شود. ‫FragmentManager مسئول تعیین وضعیت قطعه خود و سپس انتقال آن به آن وضعیت است.

علاوه‌بر چرخه حیات قطعه، FragmentManager مسئول پیوست کردن قطعات به فعالیت میزبان آن‌ها و جدا کردن آن‌ها در زمانی است که قطعه دیگر مورداستفاده نیست. کلاس Fragment دو روش فراخوانی برگشتی دارد، onAttach() و onDetach()، که می‌توانید آن‌ها را لغو کنید تا وقتی هرکدام از این رویدادها رخ داد، کار را انجام دهید.

وقتی قطعه به FragmentManager اضافه شده باشد و به فعالیت میزبانش پیوست شده باشد، فراخوانی برگشتی onAttach() فراخوانده می‌شود. در این مرحله، قطعه فعال است و FragmentManager وضعیت چرخه حیات آن را مدیریت می‌کند. در این مرحله، روش‌های FragmentManager مانند findFragmentById() این قطعه را برمی‌گردانند.

‫onAttach() همیشه قبل‌از هرگونه تغییر وضعیت چرخه حیات فراخوانده می‌شود.

وقتی قطعه از FragmentManager برداشته شود و از فعالیت میزبانش جدا شود، فراخوانی برگشتی onDetach() فراخوانده می‌شود. قطعه دیگر فعال نیست و دیگر نمی‌توان آن را بااستفاده از findFragmentById() بازیابی کرد.

‫onDetach() همیشه بعداز هرگونه تغییر وضعیت چرخه حیات فراخوانی می‌شود.

توجه داشته باشید که این فراخوانی‌های برگشتی به روش‌های FragmentTransaction attach() و detach() مربوط نیستند. برای اطلاعات بیشتر درباره این روش‌ها، تراکنش‌های Fragment را ببینید.

فراخوانی‌ها و حالت‌های چرخه حیات قطعه

هنگام تعیین وضعیت چرخه حیات قطعه، FragmentManager موارد زیر را درنظر می‌گیرد:

  • حداکثر وضعیت قطعه با FragmentManager آن تعیین می‌شود. قطعه نمی‌تواند فراتر از وضعیت FragmentManager خود پیش برود.
  • به‌عنوان بخشی از FragmentTransaction، می‌توانید بااستفاده از setMaxLifecycle() حداکثر وضعیت چرخه حیات را روی قطعه تنظیم کنید .
  • وضعیت چرخه حیات قطعه هرگز نمی‌تواند بزرگ‌تر از والد آن باشد. برای مثال، یک قطعه یا فعالیت والد باید قبل‌از قطعه‌های فرزندش شروع شود. به‌همین ترتیب، قطعه‌های فرزند باید قبل‌از قطعه یا فعالیت والدشان متوقف شوند.
حالت‌های چرخه حیات قطعه و ارتباط آن‌ها با فراخوانی‌های چرخه حیات قطعه و چرخه حیات نمای قطعه
شکل ۱. حالت‌های Fragment Lifecycle و ارتباط آن‌ها با فراخوانی‌های چرخه حیات fragment و نمای fragment Lifecycle.

شکل ۱ هریک از حالت‌های Lifecycle قطعه و نحوه ارتباط آن‌ها با فراخوانی‌های چرخه حیات قطعه و نمای Lifecycle قطعه را نشان می‌دهد.

همان‌طور که قطعه در چرخه حیات خود پیش می‌رود، در حالت‌های خود به بالا و پایین حرکت می‌کند. برای مثال، قطعه‌ای که به بالای پشته قبلی‌ها اضافه می‌شود، از CREATED به STARTED و سپس به RESUMED حرکت می‌کند. برعکس، وقتی قطعه‌ای از پشته قبلی‌ها خارج می‌شود، در این حالت‌ها به‌سمت پایین حرکت می‌کند و از RESUMED به STARTED به CREATED و درنهایت به DESTROYED می‌رود.

تبدیل حالت صعودی

وقتی قطعه در حالت‌های چرخه حیات خود به‌سمت بالا حرکت می‌کند، ابتدا فراخوانی چرخه حیات مرتبط را برای حالت جدید خود فراخوانی می‌کند. Once this callback is finished, the relevant Lifecycle.Event is emitted to observers by the fragment's Lifecycle, followed by the fragment's view Lifecycle, if it has been instantiated.

بخش ایجاد شد

وقتی قطعه شما به حالت CREATED می‌رسد، به FragmentManager اضافه شده است و روش onAttach() قبلاً فراخوانی شده است.

This would be the appropriate place to restore any saved state associated with the fragment itself through the fragment's SavedStateRegistry. توجه داشته باشید که نمای قطعه در این زمان ایجاد نشده است و هر وضعیتی که با نمای قطعه مرتبط است باید فقط پس‌از ایجاد نما بازیابی شود.

این انتقال، onCreate() فراخوانی برگشتی را فراخوانی می‌کند. همچنین، پاسخ تماس آرگومان savedInstanceState Bundle را دریافت می‌کند که حاوی هر وضعیتی است که قبلاً توسط onSaveInstanceState() ذخیره شده است. توجه داشته باشید که savedInstanceState اولین باری که قطعه ایجاد می‌شود مقدار null دارد، اما برای بازآفرینی‌های بعدی همیشه غیرتهی است، حتی اگر onSaveInstanceState() را لغو نکنید. برای جزئیات بیشتر، ذخیره کردن وضعیت با قطعه‌ها را ببینید.

Fragment CREATED and View INITIALIZED

نمای قطعه Lifecycle فقط زمانی ایجاد می‌شود که Fragment شما نمونه View معتبری ارائه دهد. در بیشتر موارد، می‌توانید از سازنده‌های قطعه استفاده کنید که @LayoutId را می‌گیرند و به‌طور خودکار نما را در زمان مناسب گسترش می‌دهند. همچنین می‌توانید onCreateView() را لغو کنید تا نمای قطعه‌تان را به‌صورت برنامه‌نویسی‌شده ایجاد یا گسترش دهید.

If and only if your fragment's view is instantiated with a non-null View, that View is set on the fragment and can be retrieved using getView(). سپس getViewLifecycleOwnerLiveData() با INITIALIZED LifecycleOwner جدید مطابق با نمای قطعه به‌روز می‌شود. فراخوانی چرخه حیات onViewCreated() نیز در این زمان فراخوانی می‌شود.

اینجا مکان مناسبی برای راه‌اندازی وضعیت اولیه نمای شما است، برای شروع مشاهده نمونه‌های LiveData که فراخوانی‌های برگشتی آن‌ها نمای قطعه را به‌روز می‌کنند، و برای راه‌اندازی آداپتورها در هر نمونه RecyclerView یا ViewPager2 در نمای قطعه شما.

Fragment و View ایجاد شد

پس‌از ایجاد نمای قطعه، وضعیت نمای قبلی (درصورت وجود) بازیابی می‌شود و سپس Lifecycle نما به وضعیت CREATED منتقل می‌شود. مالک چرخه حیات نما همچنین رویداد ON_CREATE را به ناظرانش ارسال می‌کند. در اینجا باید هر وضعیت اضافی مرتبط با نمای قطعه را بازیابی کنید.

این انتقال همچنین فراخوانی برگشتی onViewStateRestored() را فراخوانی می‌کند.

Fragment and View STARTED

اکیداً توصیه می‌شود که مؤلفه‌های آگاه از چرخه حیات را به وضعیت STARTED قطعه گره بزنید، زیرا این وضعیت تضمین می‌کند که نمای قطعه (درصورت ایجاد شدن) دردسترس است و انجام FragmentTransaction روی FragmentManager فرزند قطعه ایمن است. اگر نمای قطعه غیرتهی باشد، نمای قطعه Lifecycle بلافاصله پس‌از انتقال Lifecycle قطعه به STARTED، به STARTED منتقل می‌شود.

وقتی قطعه به STARTED تبدیل می‌شود، فراخوانی برگشتی onStart() فراخوانده می‌شود.

Fragment and View RESUMED

وقتی قطعه نمایان است، همه جلوه‌های Animator و Transition تمام شده‌اند و قطعه برای تعامل کاربر آماده است. Lifecycle قطعه به وضعیت RESUMED منتقل می‌شود و فراخوانی برگشتی onResume() فراخوانده می‌شود.

انتقال به RESUMED سیگنال مناسبی است که نشان می‌دهد کاربر اکنون می‌تواند با قطعه شما تعامل داشته باشد. قطعاتی که RESUMED نیستند نباید به‌صورت دستی روی نماهایشان تمرکز کنند یا تلاش کنند نمایان بودن روش ورودی را مدیریت کنند.

تبدیل‌های حالت نزولی

وقتی قطعه‌ای به وضعیت چرخه حیات پایین‌تری منتقل می‌شود، Lifecycle.Event مربوطه توسط نمای قطعه Lifecycle (درصورت نمونه‌سازی) به ناظران ارسال می‌شود، و سپس Lifecycle قطعه ارسال می‌شود. پس‌از انتشار رویداد چرخه حیات قطعه، قطعه فراخوانی چرخه حیات مربوطه را فراخوانی می‌کند.

بخش‌بندی و بازدید شروع شد

وقتی کاربر شروع به ترک قطعه می‌کند و درحالی‌که قطعه هنوز نمایان است، Lifecycle برای قطعه و نمای آن به حالت STARTED برمی‌گردد و رویداد ON_PAUSE را به ناظران خود ارسال می‌کند. سپس قطعه، onPause() callback خود را فراخوانی می‌کند.

Fragment و View ایجاد شد

وقتی قطعه دیگر قابل‌مشاهده نباشد، Lifecycles برای قطعه و برای نمای آن به حالت CREATED منتقل می‌شود و رویداد ON_STOP را برای ناظران خود منتشر می‌کند. این انتقال حالت نه‌تنها با متوقف شدن فعالیت یا قطعه والد، بلکه با ذخیره شدن حالت توسط فعالیت یا قطعه والد نیز راه‌اندازی می‌شود. این رفتار تضمین می‌کند که رویداد ON_STOP قبل‌از ذخیره شدن وضعیت قطعه فراخوانی می‌شود. این باعث می‌شود رویداد ON_STOP آخرین نقطه‌ای باشد که در آن انجام FragmentTransaction روی FragmentManager فرزند ایمن است.

همان‌طور که در شکل ۲ نشان داده شده است، ترتیب onStop() callback و ذخیره کردن وضعیت با onSaveInstanceState() براساس سطح API متفاوت است. برای همه سطوح میانای برنامه‌سازی کاربردی قبل‌از میانای برنامه‌سازی کاربردی ۲۸، onSaveInstanceState() قبل‌از onStop() فراخوانی می‌شود. برای میانای برنامه‌سازی کاربردی سطح ۲۸ و بالاتر، ترتیب فراخوانی معکوس می‌شود.

تفاوت‌های ترتیب فراخوانی برای()onStop و()onSaveInstanceState
شکل ۲. تفاوت‌های ترتیب تماس برای onStop() و onSaveInstanceState().

Fragment CREATED and View DESTROYED

پس‌از تکمیل همه پویانمایی‌ها و انتقال‌های خروج و جدا شدن نمای قطعه از پنجره، نمای قطعه Lifecycle به حالت DESTROYED منتقل می‌شود و رویداد ON_DESTROY را به ناظران خود ارسال می‌کند. سپس قطعه، onDestroyView() فراخوانی برگشتی خود را فراخوانی می‌کند. در این مرحله، نمای قطعه به پایان چرخه حیات خود رسیده است و getViewLifecycleOwnerLiveData() مقدار null را برمی‌گرداند.

در این مرحله، همه ارجاع‌ها به نمای قطعه باید برداشته شود تا نمای قطعه بتواند زباله‌روبی شود.

بخش ازبین رفت

If the fragment is removed, or if the FragmentManager is destroyed, the fragment's Lifecycle is moved into the DESTROYED state and sends the ON_DESTROY event to its observers. سپس قطعه، onDestroy() برگشت فراخوانی خود را فراخوانی می‌کند. در این مرحله، قطعه به پایان چرخه حیات خود رسیده است.

منابع بیشتر

برای اطلاعات بیشتر درباره چرخه حیات قطعه، به منابع اضافی زیر مراجعه کنید.

راهنماها

وبلاگ‌ها