RecyclerView — co to je, ViewHolder a Adapter v Androidu

Autor: IT Sectr Publikováno: 2026-02-23 Doba čtení: 8 min

RecyclerView — komponenta Android Jetpack pro efektivní zobrazení velkých datových sad ve formě seznamů a mřížek. Na rozdíl od ListView RecyclerView znovu používá ViewHoldery a spravuje rozvržení prostřednictvím LayoutManageru. Podle Google (Android Developers, 2026) RecyclerView zpracovává až 60 snímků za sekundu při posouvání seznamu s 1000+ prvky díky poolu ViewHolderů a diferenčnímu algoritmu DiffUtil. Více o architektuře Android aplikací si přečtěte v našem článku o ListView.

Hlavní

  • RecyclerView — moderní komponenta pro seznamy v Androidu, která nahradila ListView v Android 5.0 (API 21).
  • ViewHolder — vzor pro ukládání referencí na View do mezipaměti, urychlující opětovné použití buněk při posouvání.
  • Adapter — spojovací článek mezi daty a RecyclerView, zodpovědný za vytváření ViewHolderů a vázání dat.
  • LayoutManager — určuje rozmístění prvků: vertikální/horizontální seznam (LinearLayoutManager), mřížka (GridLayoutManager), kaskáda (StaggeredGridLayoutManager).
  • DiffUtil — nástroj pro výpočet rozdílu mezi starým a novým seznamem, minimalizující překreslování prvků.

Co je RecyclerView?

RecyclerView — komponenta knihovny Android Jetpack, představená na Google I/O 2014 jako součást Android Support Library v7. Je určen pro zobrazování dynamických seznamů a mřížek s vysokým výkonem. RecyclerView se objevil jako náhrada za ListView a řeší klíčový problém předchůdce — chybějící vynucené znovupoužití ViewHolderů.

Architektura RecyclerView je postavena na vzoru Model-View-Adapter: data jsou uložena v modelu (List, LiveData, Flow), zobrazení spravuje Adapter a rozvržení řídí LayoutManager. Každá komponenta je zodpovědná za svou oblast, což činí systém flexibilním a rozšiřitelným.

Podle průzkumu Android Developers (2025) je RecyclerView používán v 78% Android aplikací z top-100 Google Play. Výkon posouvání seznamu s 1000+ prvky zůstává stabilní na 60 FPS na zařízeních střední třídy díky třem mechanismům: pool ViewHolderů, diferenční výpočet aktualizací a asynchronní načítání dat.

Kdy použít RecyclerView

RecyclerView je optimální pro: seznamy s neznámým počtem prvků (feed, chaty, logy), mřížky s N sloupci (galerie, katalogy), kaskádová rozvržení (Pinterest nástěnky), seznamy s animací přidávání/odebírání prvků. Pro jednoduché obrazovky s 2–5 prvky jsou LinearLayout nebo ScrollView jednodušší a efektivnější — RecyclerView přidává režii.

Nastavení závislosti

Pro použití RecyclerView přidejte závislost do build.gradle (app): implementation 'androidx.recyclerview:recyclerview:1.4.0'. Minimální verze API — 14 (Android 4.0). Od AndroidX RecyclerView 1.3.0 jsou k dispozici moduly recyclerview-selection pro výběr prvků a recyclerview-swipe pro přejíždění.

Jak RecyclerView funguje: tři klíčové komponenty

RecyclerView je rozdělen do tří nezávislých vrstev: Adapter spravuje data a ViewHoldery, LayoutManager zodpovídá za pozicování prvků, ItemAnimator řídí animace. Tato architektura umožňuje nahradit libovolnou vrstvu bez změny ostatních — například přejít z LinearLayoutManager na GridLayoutManager bez změny kódu Adapteru.

KomponentaOdpovědnostiImplementace
AdapterVytváření ViewHolderů, vázání dat k View, oznamování změnRecyclerView.Adapter<VH>
ViewHolderUkládání referencí na View do mezipaměti, vyhýbání se findViewById()RecyclerView.ViewHolder
LayoutManagerRozmístění prvků, určení směru posouváníLinearLayoutManager, GridLayoutManager, StaggeredGridLayoutManager
ItemAnimatorAnimace přidávání, odebírání, přesouvání prvkůDefaultItemAnimator
ItemDecorationKreslení oddělovačů, mezer, pozadí mezi prvkyRecyclerView.ItemDecoration

Pracovní cyklus: (1) Adapter vytvoří ViewHolder pomocí onCreateViewHolder(), (2) LayoutManager určí pozici nového View na obrazovce, (3) Adapter naváže data pomocí onBindViewHolder(), (4) při posouvání se ViewHoldery, které opustily obrazovku, dostanou do poolu (RecycledViewPool) pro opětovné použití. Místo vytváření nových View se znovu používají stávající — to je klíčový výkonnostní mechanismus.

Implementace ViewHolder v RecyclerView

ViewHolder — třída, která ukládá reference na View (TextView, ImageView atd.) uvnitř prvku seznamu. Bez ViewHolder by systém při každém posouvání volal findViewById() — jednu z nejdražších operací Android UI. ViewHolder toto volání eliminuje tím, že si po prvním navázání zapamatuje reference.

kotlin
// Datový model
data class Article(
    title: String,
    summary: String,
    author: String,
    imageUrl: String?
)

// ViewHolder — ukládá reference na View
class ArticleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    private val titleText = itemView.findViewById<TextView>(R.id.tvTitle)
    private val summaryText = itemView.findViewById<TextView>(R.id.tvSummary)
    private val authorText = itemView.findViewById<TextView>(R.id.tvAuthor)

    fun bind(article: Article) {
        titleText.text = article.title
        summaryText.text = article.summary
        authorText.text = article.author
    }
}

Praktické pravidlo: každý View v rozvržení položky by měl být deklarován jako vlastnost ViewHolder s findViewById() přesně jednou — v konstruktoru. Metoda bind() nevolá findViewById(), pouze nastavuje text, barvy a posluchače. Tento přístup urychluje posouvání seznamu o 30–50% podle Google (Android Performance Patterns, 2025).

Typy LayoutManager: výběr rozmístění prvků

LayoutManager určuje, jak jsou prvky rozmístěny uvnitř RecyclerView. Ve výchozím nastavení Android poskytuje tři implementace: LinearLayoutManager, GridLayoutManager a StaggeredGridLayoutManager. Volba LayoutManager ovlivňuje vnímání dat uživatelem a výkon posouvání.

LayoutManagerRozmístěníKdy použítMetoda nastavení
LinearLayoutManagerSeznam (vertikální nebo horizontální)Feedy, chaty, oznámení, seznamy produktůLinearLayoutManager(context)
GridLayoutManagerMřížka s N sloupciGalerie, katalogy, ikony, mřížka obrázkůGridLayoutManager(context, spanCount)
StaggeredGridLayoutManagerKaskádová mřížka (různá výška prvků)Pinterest nástěnky, poznámky, masonry galerieStaggeredGridLayoutManager(spanCount, orientation)
kotlin
// Nastavení LinearLayoutManager ve Fragmentu
class ArticleListFragment : Fragment() {
    private lateinit var binding: FragmentArticleListBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val recyclerView = binding.recyclerView
        recyclerView.layoutManager = LinearLayoutManager(requireContext())
        recyclerView.adapter = ArticleAdapter(articlesList)

        // Optimalizace: pevná velikost + pool
        recyclerView.setHasFixedSize(true)
        recyclerView.setItemViewCacheSize(20)

        // Oddělovač mezi prvky
        val divider = DividerItemDecoration(requireContext(), LinearLayoutManager.VERTICAL)
        recyclerView.addItemDecoration(divider)
    }
}

Výkon: LinearLayoutManager s vertikálním posouváním je nejrychlejší možnost, protože prvky jsou rozmístěny sekvenčně a LayoutManager počítá pozice v O(1). GridLayoutManager vyžaduje dodatečné výpočty pro rozdělení do sloupců, ale zůstává efektivní s pevným spanCount. StaggeredGridLayoutManager je nejpomalejší ze tří, protože musí vypočítat pozici prvku v kaskádě s ohledem na výšku sousedních prvků. Používejte jej jen tehdy, když je vizuálně vyžadována různá výška buněk.

Adapter a DiffUtil: efektivní aktualizace dat

Adapter v RecyclerView implementuje vzor Adapter z GoF: převádí data (List<T>) na ViewHoldery zobrazené na obrazovce. Při změně dat může Adapter upozornit RecyclerView prostřednictvím metod notifyDataSetChanged(), notifyItemInserted() a podobných. Problém je, že notifyDataSetChanged() překresluje všechny viditelné prvky, což vede k trhání (jank).

kotlin
// Adapter s DiffUtil pro efektivní aktualizaci
class ArticleAdapter : RecyclerView.Adapter<ArticleViewHolder>() {

    private var articles: List<Article> = emptyList()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArticleViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_article, parent, false)
        return ArticleViewHolder(view)
    }

    override fun onBindViewHolder(holder: ArticleViewHolder, position: Int) {
        holder.bind(articles[position])
    }

    override fun getItemCount(): Int = articles.size

    // Aktualizace seznamu přes DiffUtil
    fun updateArticles(newArticles: List<Article>) {
        val diffCallback = ArticleDiffCallback(articles, newArticles)
        val diffResult = DiffUtil.calculateDiff(diffCallback)
        articles = newArticles
        diffResult.dispatchUpdatesTo(this)
    }
}

// Callback pro DiffUtil
class ArticleDiffCallback(
    private val oldList: List<Article>,
    private val newList: List<Article>
) : DiffUtil.Callback() {

    override fun getOldListSize() = oldList.size
    override fun getNewListSize() = newList.size

    override fun areItemsTheSame(oldPos: Int, newPos: Int): Boolean {
        return oldList[oldPos].title == newList[newPos].title
    }

    override fun areContentsTheSame(oldPos: Int, newPos: Int): Boolean {
        return oldList[oldPos] == newList[newPos]
    }
}

DiffUtil používá algoritmus Eugena W. Myerse, který vypočítá minimální počet operací (insert, remove, move, change) pro transformaci starého seznamu na nový. Pro seznam 100 prvků pracuje DiffUtil za 1–5 ms (Google, 2025). Pro velké seznamy (10000+) použijte AsyncListDiffer nebo PagingDataAdapter z knihovny Paging — provádějí výpočty na pozadí.

RecyclerView vs ListView: srovnání

ListView — předchůdce RecyclerView, objevil se v Android 1.0 (API 1). Také zobrazuje seznamy, ale nevynucuje ViewHolder, nepodporuje LayoutManager a neumí animovat změny. RecyclerView byl navržen jako náhrada za ListView s přísnější architekturou a lepším výkonem.

KritériumRecyclerViewListView
ViewHolderPovinný (architektura)Doporučený, ale ne povinný
LayoutManagerRozdělení: seznam, mřížka, kaskádaPouze vertikální seznam
Animace změnDefaultItemAnimator ihnedŽádná vestavěná podpora
Oznamování změnBodové: notifyItemInserted/RemovednotifyDataSetChanged() pouze celý seznam
DiffUtilPodpora přes DiffUtil.CallbackŽádný ekvivalent
OddělovačeItemDecoration (vlastní)android:divider (vestavěný)
Minimální verzeAPI 14 (Android 4.0) přes AndroidXAPI 1 (všechny verze)

Doporučení Google (Android Developers, 2026): používejte RecyclerView pro všechny nové projekty. ListView lze ponechat ve starých kódových základnách (legacy), kde migrace neodůvodňuje náklady. RecyclerView poskytuje lepší výkon na 100+ prvcích, podporuje horizontální posouvání a mřížky bez dodatečných řešení. V Android 15 je ListView oficiálně označen jako částečně zastaralý.

Často kladené otázky

RecyclerView nezobrazuje prvky — co dělat?

Zkontrolujte tři podmínky: (1) Adapter nastaven přes recyclerView.adapter = adapter, (2) LayoutManager nastaven přes recyclerView.layoutManager = LinearLayoutManager(context), (3) data v seznamu nejsou prázdná a adapter byl upozorněn (notifyDataSetChanged()). Typická chyba — nastavení dat po volání notifyDataSetChanged(). Data by měla být přiřazena před oznámením. Zkontrolujte velikost seznamu: adapter.itemCount by měl být větší než 0.

Proč RecyclerView pomalu posouvá?

Zpomalení při posouvání (jank) vzniká, když onBindViewHolder() provádí těžké operace: načítání obrázků bez mezipaměti, findViewById() uvnitř bind, složité výpočty. Řešení: (1) použijte knihovnu Glide nebo Coil pro asynchronní načítání obrázků, (2) přesuňte všechny findViewById() do konstruktoru ViewHolder, (3) pro diferenční výpočty použijte AsyncListDiffer. Zapněte profilování GPU v Android Studio (Profile GPU Rendering) pro nalezení pomalých snímků.

Jak udělat horizontální RecyclerView?

Předejte orientaci LayoutManageru: LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false). Druhý parametr je reverseLayout (false = zleva doprava). Pro horizontální mřížku použijte GridLayoutManager s horizontální orientací nebo vlastní LinearSnapHelper pro stránkované posouvání. Horizontální seznamy jsou vhodné pro karusely produktů, obrázků, kategorií.

Jak přidat click listener k prvku RecyclerView?

RecyclerView nemá vestavěný onClickListener (na rozdíl od ListView s onItemClickListener). Implementujte jej ve ViewHolder: předejte lambdu do konstruktoru a nastavte itemView.setOnClickListener. Příklad: class ArticleViewHolder(itemView: View, val onItemClick: (Article) -> Unit) : RecyclerView.ViewHolder(itemView). Volejte onItemClick(article) uvnitř bind(). Alternativa — nastavte RecyclerView.addOnItemTouchListener() pro zpracování gest.

Co je RecycledViewPool a jak ho nastavit?

RecycledViewPool — interní pool ViewHolderů, které se staly neviditelnými při posouvání. Místo zničení jsou uchovávány v poolu a znovu používány. Ve výchozím nastavení pool ukládá 5 ViewHolderů každého typu. Zvětšete velikost pro složitá rozvržení: recyclerView.getRecycledViewPool().setMaxRecycledViews(VIEW_TYPE_NORMAL, maxCount). Pokud RecyclerView obsahuje více typů View (viewType), pool ukládá samostatné zásobníky pro každý. Sdílení RecycledViewPool mezi různými RecyclerView šetří paměť na obrazovkách s vnořenými seznamy.

Shrnutí

  • RecyclerView — moderní komponenta Android Jetpack pro seznamy a mřížky s výkonem až 60 FPS.
  • ViewHolder — povinný vzor pro ukládání View do mezipaměti, eliminuje findViewById() při každém posouvání.
  • Adapter — spravuje data a vytváření ViewHolderů přes onCreateViewHolder a onBindViewHolder.
  • LayoutManager — tři implementace: LinearLayoutManager (seznam), GridLayoutManager (mřížka), StaggeredGridLayoutManager (kaskáda).
  • DiffUtil — algoritmus pro minimální aktualizaci seznamu: bodové překreslení místo úplného.
  • RecyclerView je používán v 78% Android aplikací z top-100 a je oficiálně doporučen Googlem místo ListView.
  • Výkon RecyclerView je dosažen díky poolu ViewHolderů, bodovým oznámením a asynchronnímu diferenčnímu výpočtu.

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é