ListView: co to je, jednoduché seznamy v Android aplikacích

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

ListView — základní komponent Androidu pro zobrazování vertikálních seznamů, dostupný od API 1 (Android 1.0). ListView vytváří seznam z prvků pomocí ArrayAdapter a podporuje vlastní rozvržení buněk. Zjistíme, co je ListView, jak ho nakonfigurovat a jaké nástrahy skrývá tento starý, ale stále používaný komponent. V IT Sectr se s ListView setkáváme v legacy projektech a udržujeme zpětnou kompatibilitu s Android 4.4. Pro srovnání s moderní alternativou si přečtěte článek o RecyclerView.

Hlavní body

  • ListView — vestavěný komponent Android SDK pro vertikální seznamy, který se objevil v Android 1.0.
  • ArrayAdapter — standardní adaptér pro připojení pole dat k ListView přes toString() nebo vlastní rozvržení.
  • SimpleAdapter — adaptér pro seznamy z Map dat, vhodný pro jednoduché obrazovky bez ViewModel.
  • onItemClickListener — vestavěný handler kliknutí, který nevyžaduje dodatečnou implementaci v adaptéru.
  • convertView — mechanismus opětovného použití View v ListView, který musí vývojář implementovat ručně (analogie ViewHolder).

Co je ListView v Androidu?

ListView — je skupina View z balíčku android.widget, určená k zobrazování posouvatelného seznamu prvků. ListView implementuje vzor AdapterView: data se předávají přes adaptér (Adapter), který převádí datové prvky na View zobrazovaná na obrazovce. ListView existuje v Android SDK od první verze (API 1) a nevyžaduje další knihovny.

Architektura ListView je jednodušší než RecyclerView: LayoutManager je vestavěný (pouze vertikální posouvání), animace změn chybí, oddělovače se nastavují pomocí XML atributu android:divider. ListView automaticky přidává OverScrollView a zvýraznění při fokusu, což zjednodušuje prototypování. Podle údajů Statista (2025) asi 15% Android aplikací v top-100 Play Store stále obsahuje ListView — zejména legacy projekty s minimální podporou.

Historie a aktuálnost

ListView byl hlavním komponentem seznamů v Androidu od roku 2008 do roku 2014, kdy byl na Google I/O 2014 představen RecyclerView. Navzdory statusu částečně zastaralého (soft-deprecated) zůstává ListView dostupný ve všech verzích Androidu a není označen jako @Deprecated v SDK API 35. Pokud váš projekt podporuje Android 4.4 (API 19) a nižší, je ListView jedinou vestavěnou volbou, protože RecyclerView vyžaduje AndroidX a gradle závislosti.

Typy adaptérů: ArrayAdapter a SimpleAdapter

ArrayAdapter — nejpopulárnější adaptér pro ListView. Přijímá List<T> a rozvržení pro každý prvek. Ve výchozím nastavení ArrayAdapter volá toString() pro každý objekt a zobrazuje text v simple_list_item_1 (jeden TextView). Pro vlastní zobrazení je třeba přepsat getView() nebo předat vlastní rozvržení v konstruktoru.

kotlin
// ListView s ArrayAdapter (jednoduchý text)
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val countries = listOf(
        "Rusko", "USA", "Německo",
        "Francie", "Japonsko", "Čína", "Brazílie"
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val adapter = ArrayAdapter<String>(
            this,
            android.R.layout.simple_list_item_1,
            countries
        )
        binding.listView.adapter = adapter

        // Zpracování kliknutí
        binding.listView.onItemClickListener =
            AdapterView.OnItemClickListener { _, _, position, _ ->
                Toast.makeText(this, countries[position], Toast.LENGTH_SHORT).show()
            }
    }
}

SimpleAdapter je určen pro seznamy z Map dat. Přijímá List<Map<String, Any>> a pole from/to pro propojení klíčů Map s ID widgetů v rozvržení. SimpleAdapter je vhodný pro rychlé prototypy, když není potřeba samostatná třída adaptéru. Nevýhoda — chybí type-safe typování a složitost s vlastní logikou.

xml
<!-- Rozvržení s ListView -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@color/divider"
        android:dividerHeight="1px"
        android:scrollbars="vertical" />
</LinearLayout>

Vytvoření vlastního adaptéru s ViewHolder

Vlastní adaptér pro ListView přepisuje metodu getView(), kterou RecyclerView rozděluje na onCreateViewHolder + onBindViewHolder. V ListView jsou oba kroky sloučeny, proto musí vývojář implementovat vzor ViewHolder samostatně pomocí convertView (znovu použitelné View) a tagu setTag().

kotlin
// Datový model
data class Product(
    name: String,
    price: String,
    imageResId: Int
)

// Vlastní adaptér s ViewHolder
class ProductAdapter(
    context: Context,
    private val products: List<Product>
) : ArrayAdapter<Product>(context, 0, products) {

    // ViewHolder pro cachování
    private class ViewHolder(view: View) {
        val nameText: TextView = view.findViewById(R.id.tvName)
        val priceText: TextView = view.findViewById(R.id.tvPrice)
        val imageView: ImageView = view.findViewById(R.id.ivProduct)
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val view = convertView ?: LayoutInflater.from(context)
            .inflate(R.layout.item_product, parent, false)
            .also { it.tag = ViewHolder(it) }

        val holder = view.tag as ViewHolder
        val product = getItem(position)

        holder.nameText.text = product.name
        holder.priceText.text = product.price
        holder.imageView.setImageResource(product.imageResId)

        return view
    }
}

Klíčový rozdíl od RecyclerView: v ListView se metoda getView() volá při každém objevení prvku na obrazovce. Pokud se nepoužije convertView a ViewHolder, každé posouvání vytváří nový objekt View, což vede k únikům paměti a zpožděním na seznamech s 50+ prvky. ViewHolder s view.tag — povinná optimalizace pro ListView s vlastními rozvrženími.

Omezení ListView: proč Google doporučuje RecyclerView

ListView má čtyři architektonická omezení, která Google opravil v RecyclerView: (1) pouze vertikální orientace — žádné mřížky, horizontální seznamy nebo kaskády; (2) chybí bodová oznámení — jakákoli změna dat způsobuje úplné překreslení přes notifyDataSetChanged(), což vytváří trhání; (3) žádná vestavěná animace přidávání/odebírání prvků; (4) žádné oddělení odpovědností — LayoutManager je vestavěný, ItemAnimator chybí.

xml
<!-- item_product.xml — rozvržení prvku ListView -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="12dp">

    <ImageView
        android:id="@+id/ivProduct"
        android:layout_width="56dp"
        android:layout_height="56dp"
        android:scaleType="centerCrop" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        android:paddingStart="12dp">

        <TextView
            android:id="@+id/tvName"
            android:textSize="16sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/tvPrice"
            android:textSize="14sp"
            android:textColor="@color/price" />
    </LinearLayout>
</LinearLayout>

Praktické důsledky: na seznamech do 20 prvků funguje ListView stejně rychle jako RecyclerView. Při 100+ prvcích je rozdíl znatelný: ListView začíná ztrácet FPS kvůli chybějícím diferenčním výpočtům a vynucenému ViewHolder. Pro seznamy s častými aktualizacemi (chat, feed, logy) není ListView vhodný — použijte RecyclerView s Paging 3. V IT Sectr migrujeme ListView na RecyclerView při každé práci na legacy obrazovkách s více než 50 prvky.

Konfigurace ListView přes XML atributy

ListView poskytuje sadu XML atributů pro rychlou konfiguraci bez kódu: android:divider (barva/obrázek oddělovače), android:dividerHeight (tloušťka), android:scrollbars (posuvníky), android:fastScrollEnabled (rychlé posouvání pomocí úchytu), android:choiceMode (režim výběru: singleChoice, multipleChoice). Atribut android:entries umožňuje naplnit seznam z pole zdrojů (string-array) bez adaptéru.

AtributPopisPříklad hodnoty
android:dividerBarva nebo drawable oddělovače@color/gray_light
android:dividerHeightTloušťka oddělovače v px/dp1dp
android:entriesPole řetězců ze zdrojů@array/countries
android:choiceModeRežim výběru prvkusingleChoice
android:fastScrollEnabledRychlé posouvánítrue
android:overlapAnchorKotva pro rozbalovací seznamy (API 21+)true

Režim výběru: choiceMode="singleChoice" aktivuje styl RadioButton, při kterém je vybraný prvek zvýrazněn. choiceMode="multipleChoice" — zaškrtávací políčka pro více prvků. Data výběru jsou dostupná přes listView.checkedItemPosition nebo listView.checkedItemIds. Důležité: při choiceMode používá ListView StateListDrawable pro pozadí — nastavte vlastní selektor, pokud standardní modrá nevyhovuje designu.

ListView vs RecyclerView: srovnání možností

Výběr mezi ListView a RecyclerView závisí na požadavcích projektu. RecyclerView je moderní standard, ale ListView může být ospravedlnitelný pro jednoduché obrazovky s minimálními náklady na údržbu starého kódu. Srovnání podle všech klíčových parametrů:

ParametrListViewRecyclerView
Velikost knihovnyVestavěný v SDK (≈60 KB)AndroidX (≈300 KB se závislostmi)
Minimální verzeAPI 1API 14 (přes AndroidX)
OrientacePouze vertikálníVertikální, horizontální, mřížka, kaskáda
ViewHolderRuční implementacePovinný architekturou
AnimacePouze fade přechodyDefaultItemAnimator (add, remove, move, change)
Bodové aktualizaceNe (pouze notifyDataSetChanged)notifyItemInserted/Removed/Changed
Click listeneronItemClickListener (vestavěný)Přes ViewHolder (není vestavěný)
VýkonDostačující pro seznamy do 50 prvkůStabilních 60 FPS pro 1000+ prvků

Závěr: pro nové projekty používejte RecyclerView. ListView ponechte pouze v legacy kódu, kde je migrace neospravedlnitelně drahá. Podle pokynů Material Design 3 (2026) by seznamy jakékoli složitosti měly používat RecyclerView pro soulad s moderními standardy výkonu a přístupnosti.

Často kladené otázky

Je ListView zastaralý nebo ne?

ListView není označen jako @Deprecated v Android SDK API 35, ale Google nedoporučuje jeho použití v nových projektech (soft-deprecated). Komponent zůstává funkční ve všech verzích Androidu. RecyclerView je oficiální náhradou od roku 2014. Pokud začínáte nový projekt — zvolte RecyclerView. Pokud udržujete stávající — ListView bude nadále fungovat bez změn.

Jak přidat header/footer do ListView?

ListView podporuje metody addHeaderView(View, Object, boolean) a addFooterView(View, Object, boolean). Header a footer se přidávají do obecného seznamu prvků, ale neúčastní se adaptéru — vždy se zobrazují na začátku a konci seznamu. Důležité: přidávejte header/footer před nastavením adaptéru (setAdapter()), jinak nebudou zohledněny. Po přidání header se ID pozic prvků posunou o počet headerů.

Proč se ListView neposouvá uvnitř ScrollView?

ListView a ScrollView oba zpracovávají vertikální gesta, což vytváří konflikt: vnější ScrollView zachytává posouvání a ListView se neposouvá. Řešení: (1) nevkládejte ListView do ScrollView — použijte RecyclerView s NestedScrollingChild, (2) nahraďte ScrollView za NestedScrollView (API 21+), (3) použijte ListView s pevnou výškou (android:layout_height="...dp") uvnitř ScrollView, ale to zlomí přizpůsobivost.

Jak vyčistit ListView a aktualizovat data?

Čištění dat v ListView závisí na typu adaptéru. Pro ArrayAdapter: adapter.clear() a adapter.addAll(newList) s následným adapter.notifyDataSetChanged(). Pro vlastní adaptér: aktualizujte seznam dat a zavolejte notifyDataSetChanged(). Pozor: listView.invalidateViews() pouze překresluje View, ale neaktualizuje data. Vždy měňte data přes adaptér, ne přímo.

Jak změnit výšku prvku ListView?

Výška prvku ListView se nastavuje v rozvržení item. Pokud rozvržení používá layout_height="wrap_content", výška se přizpůsobí obsahu. Pro pevnou výšku všech prvků použijte vlastní adaptér, který nastavuje LayoutParams v getView(): view.layoutParams.height = resources.getDimensionPixelSize(R.dimen.itemHeight). Pro různorodé výšky použijte RecyclerView s různými typy zobrazení.

Shrnutí

  • ListView — základní komponent Android SDK pro vertikální seznamy, dostupný od API 1.
  • ArrayAdapter — nejjednodušší adaptér pro seznam řetězců; pro vlastní rozvržení je potřeba přepsaný getView().
  • ViewHolder v ListView se implementuje ručně přes convertView a view.tag — povinná podmínka výkonu.
  • ListView podporuje choiceMode (single/multiple), header/footer, fastScroll a android:entries bez adaptéru.
  • Omezení ListView: pouze vertikální orientace, chybějící animace, úplné překreslení při každé změně.
  • ListView není označen jako zastaralý, ale Google doporučuje RecyclerView pro všechny nové projekty.
  • Pro seznamy do 50 prvků je ListView dostačující; pro vše složitější — použijte RecyclerView.

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é