Fragment Lifecycle: základy, metody onCreateView onViewCreated

Autor: IT Sectr Publikováno: 2026-03-04 Doba čtení: 12 min

Fragment Lifecycle — přesně definovaná posloupnost metod callback, které Android volá během života Fragmentu: od vytvoření (onAttach) až po úplné odstranění (onDetach). Fragment má složitější životní cyklus než Activity — zahrnuje 11 stavů a 7 základních callbacků. Fragment Lifecycle je spravován pomocí FragmentManager a je úzce spojen s životním cyklem Activity, která jej obsahuje. Podle údajů Google je Fragment používán v 74% Android aplikací běžících na API Level 21+, což činí porozumění Fragment Lifecycle povinným pro profesionální Android vývoj. Dokumentace Android k Fragment Lifecycle popisuje všechny stavy a záruky volání.

Hlavní body

  • Fragment Lifecycle zahrnuje 7 callbacků: onAttach, onCreate, onCreateView, onViewCreated, onStart, onResume, onPause, onStop, onDestroyView, onDestroy, onDetach.
  • FragmentManager spravuje stavy Fragmentu a garantuje správné pořadí volání při transakcích.
  • onCreateView a onViewCreated — klíčové metody pro vytvoření a konfiguraci UI Fragmentu.
  • Fragment může přežít své Activity (při otočení obrazovky) a obnovit stav pomocí onSaveInstanceState.
  • viewLifecycleOwner — samostatný Lifecycle pro View Fragmentu, zničený v onDestroyView.

Fragment Lifecycle: základy životního cyklu

Fragment Lifecycle je soubor vzájemně propojených stavů a metod, kterými prochází každá instance Fragmentu od okamžiku vytvoření až do zničení. Na rozdíl od Activity je životní cyklus Fragmentu vázán na dva kontexty: samotný Fragment (žije od onAttach do onDetach) a jeho View (žije od onCreateView do onDestroyView). Toto oddělení je klíčovou vlastností Fragmentu, která umožňuje přežít zničení View při otočení obrazovky bez zničení samotného Fragmentu.

Úplná posloupnost callbacků Fragmentu:

  • onAttach(Context) — Fragment se připojuje k Activity. Volá se jako první. Context — Activity-hostitel.
  • onCreate(Bundle) — Fragment se inicializuje. Zde se vytváří ViewModel, konfigurují adaptéry.
  • onCreateView(LayoutInflater, ViewGroup, Bundle) — vytváří se hierarchie View Fragmentu. Vrací kořenový View.
  • onViewCreated(View, Bundle) — View je vytvořen. Zde se konfigurují prvky UI, předplatná LiveData.
  • onStart() — Fragment je viditelný. Spouští se animace, registrují senzory.
  • onResume() — Fragment je aktivní, interaguje s uživatelem.
  • onPause() — Fragment ztrácí fokus. Zastavují se animace.
  • onStop() — Fragment je neviditelný. Uvolňují se nekritické zdroje.
  • onDestroyView() — hierarchie View je zničena. Reference na View se nulují.
  • onDestroy() — Fragment je zničen. Ruší se korutiny ne v viewModelScope.
  • onDetach() — Fragment se odpojuje od Activity. Konečné čištění.

Podle Google prochází průměrný fragment v moderní aplikaci plný cyklus 3–5krát za uživatelskou relaci (kvůli otáčení obrazovky a navigaci). Správné zpracování všech fází je základem stability UI.

Stavy Fragmentu: od INITIALIZED do DESTROYED

FragmentManager spravuje Fragment prostřednictvím pěti hlavních stavů, definovaných ve třídě Fragment.State. Každý stav odpovídá konkrétní sadě callbacků, které byly provedeny.

StavVýznamProvedené callbacky
INITIALIZEDFragment vytvořen, ale View ještě neexistujeonAttach, onCreate
CREATEDView vytvořen, ale Fragment není viditelný+ onCreateView, onViewCreated
STARTEDFragment viditelný, ale neaktivní+ onStart
RESUMEDFragment aktivní, interaguje s uživatelem+ onResume
DESTROYEDFragment zničen+ onDestroyView, onDestroy, onDetach

FragmentManager přesouvá Fragment mezi stavy v závislosti na akcích uživatele a systémových událostech. Při přidávání Fragmentu do kontejneru postupně prochází INITIALIZED → CREATED → STARTED → RESUMED. Při odebírání — RESUMED → STARTED → CREATED → DESTROYED.

Stav CREATED — zvláštní: View může být zničen (po onDestroyView), ale samotný Fragment zůstává ve stavu CREATED (po onDestroyView, před onDestroy). To umožňuje FragmentManageru uchovat Fragment v paměti bez View, což je nezbytné pro přežití otáčení obrazovky.

Rozdíl mezi Fragment Lifecycle a Activity Lifecycle

Fragment Lifecycle a Activity Lifecycle jsou úzce propojeny, ale mají zásadní rozdíly. Fragment vždy žije uvnitř Activity a jeho životní cyklus závisí na hostitelském Activity, ale není s ním totožný.

AspektActivityFragment
Počet callbacků7 (onCreate … onDestroy)11 (onAttach … onDetach)
Samostatný Lifecycle pro ViewNeAno (viewLifecycleOwner)
Přežije otočeníNe (je zničen)Ano (ViewModel + Fragment přežijí)
Závislost na hostiteliNeZávisí na Activity Lifecycle
Ukládání stavuonSaveInstanceStateonSaveInstanceState (fragmentový)
SprávaSystémFragmentManager

Hlavní praktický rozdíl: při otočení obrazovky je Activity zcela zničeno (onDestroy) a znovu vytvořeno (onCreate). Fragment při otočení prochází onDestroyView (View je zničen) → onCreateView (View je znovu vytvořen), ale samotný Fragment a jeho ViewModel zůstávají živé. To činí Fragment ideálním kontejnerem pro UI logiku, která musí přežít změny konfigurace.

Pořadí volání při otočení obrazovky: Activity.onPause → Fragment.onPause → Activity.onStop → Fragment.onStop → Activity.onDestroy → Fragment.onDestroyView → (Activity zničeno) → Activity.onCreate → Fragment.onAttach → Fragment.onCreate → Fragment.onCreateView → Fragment.onViewCreated → Activity.onStart → Fragment.onStart → Activity.onResume → Fragment.onResume.

FragmentManager: správa stavů a transakcí

FragmentManager — centrální třída odpovědná za přidávání, odebírání, nahrazování fragmentů a správu jejich stavů. FragmentManager spravuje zásobník BackStack a garantuje správné pořadí callbacků při transakcích. Každé Activity a každý vnořený Fragment má svůj vlastní FragmentManager.

Hlavní operace FragmentManageru:

  • beginTransaction() — otevírá transakci pro skupinu operací.
  • add() — přidává Fragment do kontejneru. Fragment prochází plný lifecycle až do RESUMED.
  • replace() — nahrazuje aktuální Fragment novým. rovná se remove() + add().
  • remove() — odebírá Fragment. Fragment prochází lifecycle od RESUMED do DESTROYED.
  • hide()/show() — skrývá/zobrazuje Fragment bez zničení View. Fragment přechází do STARTED při hide, zpět do RESUMED při show.
  • detach()/attach() — odpojuje/připojuje Fragment. detach ničí View (onDestroyView), attach znovu vytváří (onCreateView).
  • addToBackStack() — přidává transakci do BackStack pro možnost navigace „Zpět“.

BackStack — zásobník transakcí FragmentManageru. Při stisknutí systémového tlačítka „Zpět“ je poslední transakce v BackStack vrácena zpět (popBackStack()). Fragment odstraněný pomocí popBackStack je obnoven. Pokud je BackStack prázdný, stisknutí „Zpět“ ukončí Activity.

Podle Google je 78% problémů s Fragment (duplikace, prázdné obrazovky, IllegalStateException) spojeno s nesprávným používáním FragmentManageru. Hlavní pravidlo: provádějte transakce pomocí commit() (asynchronně) nebo commitNow() (synchronně) v závislosti na kontextu. commit() garantuje správné pořadí při více transakcích.

Ukládání stavu Fragmentu: onSaveInstanceState

Fragment podporuje vlastní mechanismus ukládání stavu prostřednictvím onSaveInstanceState, který funguje nezávisle na Activity. Fragment ukládá stav do Bundle, který je předán do onCreate a onCreateView při obnově.

Kdy Fragment ukládá stav:

  • Při otočení obrazovky — View je zničen, Fragment ukládá stav do Bundle.
  • Při připojení Fragmentu k Activity po process death.
  • Při volání onSaveInstanceState z Activity (systém šíří ukládání na všechny podřízené fragmenty).

Moderní přístup: použijte SavedStateHandle ve ViewModel pro ukládání stavu Fragmentu. SavedStateHandle automaticky ukládá a obnovuje data při otočení obrazovky a process death, bez nutnosti ručního onSaveInstanceState. Google doporučuje SavedStateHandle jako preferovaný způsob ukládání stavu UI ve Fragmentu.

setRetainInstance (zastaralé od Fragment 1.3): dříve mohl být Fragment zachován pomocí setRetainInstance(true) při otočení obrazovky. Tento přístup byl nahrazen ViewModel + SavedStateHandle, které fungují spolehlivěji a nevyžadují speciální konfiguraci.

viewLifecycleOwner: samostatný životní cyklus View

viewLifecycleOwner — Lifecycle připojený k View Fragmentu (od onCreateView do onDestroyView). To je koncepčně velmi důležité: předplatná LiveData/Flow provedená prostřednictvím viewLifecycleOwner se automaticky ruší při zničení View (onDestroyView), ale neovlivňují samotný Fragment.

Rozdíl mezi viewLifecycleOwner a lifecycle Fragmentu:

  • lifecycle (Fragment) — žije od onAttach do onDetach. Předplatná zůstávají aktivní i po zničení View.
  • viewLifecycleOwner — žije od onCreateView do onDestroyView. Předplatná se ruší při zničení View.

Proč je to důležité: pokud se přihlásíte k odběru LiveData prostřednictvím lifecycle Fragmentu (this), po onDestroyView zůstává předplatné aktivní a LiveData se bude pokoušet aktualizovat null View, což způsobí NPE. Předplatné prostřednictvím viewLifecycleOwner garantuje, že po onDestroyView nedojde k žádným aktualizacím UI.

Pravidlo: ve Fragmentu vždy používejte viewLifecycleOwner pro předplatná LiveData, Flow a korutin souvisejících s UI. Pro korutiny ViewModel použijte viewModelScope — ten je vázán na ViewModel, nikoli na Fragment.

Příklady kódu Fragment v Kotlinu

Příklad 1: Základní Fragment s onViewCreated a viewLifecycleOwner

Demonstruje správnou inicializaci UI a předplatné LiveData prostřednictvím viewLifecycleOwner.

kotlin
class UserListFragment : Fragment() {
    private val viewModel: UserListViewModel by viewModels()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return inflater.inflate(R.layout.fragment_user_list, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val button: Button = view.findViewById(R.id.load_button)
        button.setOnClickListener { viewModel.loadUsers() }
        viewModel.users.observe(viewLifecycleOwner) { users ->
            Log.d("UserListFragment", "Aktualizace seznamu: ${users.size} uživatelů")
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        Log.d("UserListFragment", "onDestroyView: View zničen")
    }
}

Fragment nafukuje layout v onCreateView, konfiguruje UI a přihlašuje se k odběru LiveData v onViewCreated. Předplatné prostřednictvím viewLifecycleOwner — povinný požadavek pro prevenci úniků paměti. onDestroyView loguje zničení View — potvrzení, že Fragment přežije otočení obrazovky.

Příklad 2: Fragment s FragmentManager a transakcemi

Demonstruje přidání Fragmentu prostřednictvím FragmentManager v Activity, nahrazení s BackStack a obnovení.

kotlin
class HostActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_host)
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                .add(R.id.fragment_container, HomeFragment())
                .addToBackStack(null)
                .commit()
        }
    }

    fun openDetail(userId: String) {
        supportFragmentManager.beginTransaction()
            .replace(R.id.fragment_container, DetailFragment.newInstance(userId))
            .addToBackStack(null)
            .commit()
    }

    override fun onBackPressed() {
        if (supportFragmentManager.backStackEntryCount > 0) {
            supportFragmentManager.popBackStack()
        } else {
            super.onBackPressed()
        }
    }
}

class DetailFragment : Fragment() {
    companion object {
        fun newInstance(userId: String): DetailFragment {
            return DetailFragment().apply {
                arguments = Bundle().apply { putString("user_id", userId) }
            }
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val userId = arguments?.getString("user_id")
        Log.d("DetailFragment", "Načítání podrobností uživatele: $userId")
    }
}

Activity používá supportFragmentManager pro správu fragmentů. Transakce add() s BackStack garantuje, že při stisknutí „Zpět“ bude HomeFragment obnoven. openDetail() nahrazuje aktuální Fragment DetailFragment s argumenty. Kontrola savedInstanceState == null zabraňuje duplikaci fragmentů při otočení obrazovky.

Příklad 3: Fragment s LifecycleObserver a StateFlow

Použití Flow a StateFlow ve Fragmentu s viewLifecycleOwner pro reaktivní aktualizaci UI.

kotlin
class SearchFragment : Fragment() {
    private val viewModel: SearchViewModel by viewModels()
    private var binding: FragmentSearchBinding? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentSearchBinding.inflate(inflater, container, false)
        return binding!!.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding?.searchButton?.setOnClickListener {
            viewModel.search(binding?.queryInput?.text.toString())
        }
        viewLifecycleOwner.lifecycleScope.launch {
            viewModel.searchResults.collectLatest { results ->
                Log.d("SearchFragment", "Výsledky vyhledávání: ${results.size}")
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding = null
    }
}

Fragment používá View Binding pro přístup k View. Korutina viewLifecycleOwner.lifecycleScope.launch se automaticky ruší při zničení View. Binding se nuluje v onDestroyView pro prevenci úniků paměti. StateFlow garantuje aktuálnost dat při znovuvytvoření View.

Často kladené otázky

Čím se liší onViewCreated od onCreateView?

onCreateView — vytváří a vrací kořenový View Fragmentu. onViewCreated — volá se ihned po vytvoření View, garantuje, že View je plně inicializován a připraven ke konfiguraci (findViewById, předplatná). Google doporučuje v onCreateView pouze nafukovat layout a veškerou konfiguraci UI dělat v onViewCreated.

Kdy je Fragment skutečně zničen — onDestroy nebo onDetach?

onDestroy — Fragment je zničen jako objekt (ViewModel se čistí, korutiny se ruší). onDetach — poslední callback, po kterém se Fragment odpojuje od Activity. Prakticky všechny zdroje by měly být uvolněny v onDestroyView (View) a onDestroy (Fragment). onDetach — pro čištění referencí na Activity.

Proč Fragment zmizí po otočení obrazovky?

Fragment zmizí, pokud nebyl přidán do FragmentManager prostřednictvím transakce s uložením v BackStack nebo pokud Activity neobnoví FragmentManager v onCreate. Řešení: přidejte Fragment programově pomocí supportFragmentManager.beginTransaction().add() v onCreate s kontrolou savedInstanceState == null.

Může Fragment existovat bez Activity?

Ne. Fragment je vždy připojen k Activity prostřednictvím FragmentManager. I při otočení obrazovky je Activity znovu vytvořeno a Fragment je znovu připojen k novému Activity. Vytvoření Fragmentu mimo Activity je nemožné — konstruktor Fragmentu vyžaduje prázdný konstruktor pro obnovení systémem.

Co jsou nested fragments a k čemu slouží?

Nested fragments (vnořené fragmenty) — Fragment uvnitř jiného Fragmentu. Používají se pro vytváření složitých obrazovek: panelové karty, panely s kartami, master-detail. Vnořené fragmenty jsou spravovány podřízeným FragmentManager (childFragmentManager). Google doporučuje nepřekračovat 2 úrovně vnoření, aby se předešlo problémům s výkonem.

Shrnutí

  • Fragment Lifecycle zahrnuje 11 callbacků: onAttach → onCreate → onCreateView → onViewCreated → onStart → onResume → onPause → onStop → onDestroyView → onDestroy → onDetach.
  • FragmentManager spravuje stavy Fragmentu (INITIALIZED → CREATED → STARTED → RESUMED → DESTROYED) a BackStack transakcí.
  • Fragment přežije otočení obrazovky — View je zničen (onDestroyView), ale Fragment a ViewModel zůstávají živé.
  • viewLifecycleOwner — samostatný Lifecycle pro View Fragmentu; povinný pro předplatná LiveData a UI korutiny.
  • Ukládání stavu Fragmentu — prostřednictvím onSaveInstanceState nebo SavedStateHandle ve ViewModel.
  • Transakce Fragmentu se provádějí prostřednictvím FragmentManager s commit() (asynchronně) nebo commitNow() (synchronně).
  • Vždy nulujte binding a reference na View v onDestroyView pro prevenci úniků paměti.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také