ListView: ano ito, mga simpleng listahan sa Android apps

May-akda: IT Sectr Nai-publish: 2026-02-23 Oras ng pagbabasa: 8 min

ListView — pangunahing Android component para sa pagpapakita ng mga vertical na listahan, available mula API 1 (Android 1.0). Gumagawa ang ListView ng listahan mula sa mga elemento gamit ang ArrayAdapter at sumusuporta sa custom na cell layout. Alamin kung ano ang ListView, paano ito i-configure, at anong mga pitfalls ang tinatago ng luma ngunit ginagamit pa ring component na ito. Sa IT Sectr nakakasalubong namin ang ListView sa legacy-proyekto at sinusuportahan ang backward compatibility sa Android 4.4. Para sa paghahambing sa modernong alternatibo basahin ang artikulo tungkol sa RecyclerView.

Mga Pangunahing

  • ListView — built-in na Android SDK component para sa vertical na listahan, lumabas sa Android 1.0.
  • ArrayAdapter — standard na adapter para sa pagbind ng array ng data sa ListView sa pamamagitan ng toString() o custom na layout.
  • SimpleAdapter — adapter para sa mga listahan mula sa Map-data, maginhawa para sa simpleng screen na walang ViewModel.
  • onItemClickListener — built-in na click handler na hindi nangangailangan ng karagdagang implementasyon sa adapter.
  • convertView — mekanismo ng pag-reuse ng View sa ListView na dapat manual na i-implement ng developer (analogo ng ViewHolder).

Ano ang ListView sa Android?

ListView — ay isang View group mula sa package na android.widget, na idinisenyo para sa pagpapakita ng naka-scroll na listahan ng mga elemento. Ini-implement ng ListView ang pattern na AdapterView: ang data ay ipinapasa sa pamamagitan ng adapter (Adapter), na nagco-convert ng data elements sa View na ipinapakita sa screen. Ang ListView ay nasa Android SDK mula pa sa unang bersyon (API 1) at hindi nangangailangan ng karagdagang library.

Arkitektura ng ListView ay mas simple kaysa RecyclerView: LayoutManager ay built-in (vertical scroll lang), walang animation ng pagbabago, ang mga divider ay nakatakda sa pamamagitan ng XML attribute na android:divider. Awtomatikong nagdadagdag ang ListView ng OverScrollView at pag-highlight sa focus, na nagpapasimple ng prototyping. Ayon sa datos ng Statista (2025), humigit-kumulang 15% ng Android apps sa top-100 Play Store ay naglalaman pa rin ng ListView — pangunahin ang legacy-proyekto na may minimal na suporta.

Kasaysayan at Kaugnayan

Ang ListView ay ang pangunahing component ng listahan sa Android mula 2008 hanggang 2014, nang ipakilala ang RecyclerView sa Google I/O 2014. Sa kabila ng status na bahagyang luma (soft-deprecated), nananatiling available ang ListView sa lahat ng bersyon ng Android at hindi minarkahan bilang @Deprecated sa SDK API 35. Kung ang iyong proyekto ay sumusuporta sa Android 4.4 (API 19) at mas mababa, ang ListView ay ang tanging built-in na pagpipilian, dahil ang RecyclerView ay nangangailangan ng AndroidX at gradle dependencies.

Mga Uri ng Adapter: ArrayAdapter at SimpleAdapter

ArrayAdapter — ang pinakasikat na adapter para sa ListView. Tumatanggap ito ng List<T> at layout para sa bawat elemento. Bilang default, tinatawagan ng ArrayAdapter ang toString() para sa bawat object at ipinapakita ang text sa simple_list_item_1 (isang TextView). Para sa custom na pagpapakita kailangang i-override ang getView() o magpasa ng custom na layout sa constructor.

kotlin
// ListView na may ArrayAdapter (simpleng text)
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val countries = listOf(
        "Russia", "USA", "Germany",
        "France", "Japan", "China", "Brazil"
    )

    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

        // Paghawak ng click
        binding.listView.onItemClickListener =
            AdapterView.OnItemClickListener { _, _, position, _ ->
                Toast.makeText(this, countries[position], Toast.LENGTH_SHORT).show()
            }
    }
}

SimpleAdapter ay para sa mga listahan mula sa Map-data. Tumatanggap ito ng List<Map<String, Any>> at array na from/to para sa pagbind ng Map keys sa ID ng widgets sa layout. Ang SimpleAdapter ay maginhawa para sa mabilis na prototype kapag hindi kailangan ang hiwalay na adapter class. Disbentahe — kawalan ng type-safe typing at kahirapan sa custom na logic.

xml
<!-- Layout na may 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>

Paggawa ng Custom na Adapter na may ViewHolder

Custom na adapter para sa ListView ay nag-o-override ng method na getView(), na hinahati ng RecyclerView sa onCreateViewHolder + onBindViewHolder. Sa ListView ang parehong hakbang ay pinagsama, kaya ang developer ay dapat mag-implement ng pattern na ViewHolder nang nakapag-iisa sa pamamagitan ng convertView (reusable na View) at tag na setTag().

kotlin
// Modelo ng data
data class Product(
    name: String,
    price: String,
    imageResId: Int
)

// Custom na adapter na may ViewHolder
class ProductAdapter(
    context: Context,
    private val products: List<Product>
) : ArrayAdapter<Product>(context, 0, products) {

    // ViewHolder para sa caching
    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
    }
}

Pangunahing pagkakaiba sa RecyclerView: sa ListView ang method na getView() ay tinatawagan para sa bawat paglitaw ng elemento sa screen. Kung hindi ginagamit ang convertView at ViewHolder, bawat scroll ay lumilikha ng bagong View object, na nagreresulta sa memory leak at lag sa mga listahan na may 50+ elemento. ViewHolder na may view.tag — sapilitang optimization para sa ListView na may custom na layout.

Mga Limitasyon ng ListView: bakit inirerekomenda ng Google ang RecyclerView

ListView ay may apat na architectural na limitasyon na inayos ng Google sa RecyclerView: (1) vertical orientation lang — walang grids, horizontal na listahan, o cascades; (2) kawalan ng point notification — anumang pagbabago sa data ay nagdudulot ng kumpletong pag-redraw sa pamamagitan ng notifyDataSetChanged(), na lumilikha ng jerking; (3) walang built-in na animation ng pagdagdag/pag-alis ng elemento; (4) walang paghihiwalay ng responsibilidad — LayoutManager ay built-in, ItemAnimator ay wala.

xml
<!-- item_product.xml — layout ng elemento ng 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>

Praktikal na kahihinatnan: sa listahan hanggang 20 elemento, ang ListView ay gumagana nang kasing bilis ng RecyclerView. Sa 100+ elemento, ang pagkakaiba ay nagiging kapansin-pansin: ang ListView ay nagsisimulang mawalan ng FPS dahil sa kawalan ng differential calculations at sapilitang ViewHolder. Para sa mga listahan na may madalas na pag-update (chat, feed, log) ang ListView ay hindi angkop — gamitin ang RecyclerView na may Paging 3. Sa IT Sectr, mina-migrate namin ang ListView sa RecyclerView sa bawat trabaho sa legacy screen na may higit sa 50 elemento.

Pag-configure ng ListView sa pamamagitan ng XML Attributes

ListView ay nagbibigay ng set ng XML attributes para sa mabilis na pag-configure nang walang code: android:divider (kulay/drawing ng divider), android:dividerHeight (kapal), android:scrollbars (scroll bars), android:fastScrollEnabled (mabilis na scroll sa pamamagitan ng handle), android:choiceMode (mode ng pagpili: singleChoice, multipleChoice). Ang attribute na android:entries ay nagpapahintulot na punan ang listahan mula sa resource array (string-array) nang walang adapter.

AttributePaglalarawanHalimbawang Halaga
android:dividerKulay o drawable ng divider@color/gray_light
android:dividerHeightKapal ng divider sa px/dp1dp
android:entriesArray ng strings mula sa resources@array/countries
android:choiceModeMode ng pagpili ng elementosingleChoice
android:fastScrollEnabledMabilis na scrolltrue
android:overlapAnchorAnchor para sa popup listahan (API 21+)true

Mode ng pagpili: choiceMode="singleChoice" ay nag-a-activate ng RadioButton style, kung saan ang napiling elemento ay naka-highlight. choiceMode="multipleChoice" — checkbox para sa maraming elemento. Ang data ng pagpili ay available sa pamamagitan ng listView.checkedItemPosition o listView.checkedItemIds. Mahalaga: sa choiceMode ang ListView ay gumagamit ng StateListDrawable para sa background — mag-set ng sarili mong selector kung ang default na asul ay hindi tugma sa disenyo.

ListView vs RecyclerView: paghahambing ng mga kakayahan

Pagpipilian sa pagitan ng ListView at RecyclerView ay depende sa mga kinakailangan ng proyekto. Ang RecyclerView ay modernong standard, ngunit ang ListView ay maaaring maging makatwiran para sa simpleng screen na may minimal na gastos sa pagpapanatili ng lumang code. Paghahambing ayon sa lahat ng key parameter:

ParameterListViewRecyclerView
Laki ng LibraryBuilt-in sa SDK (≈60 KB)AndroidX (≈300 KB na may dependencies)
Pinakamababang BersyonAPI 1API 14 (sa pamamagitan ng AndroidX)
OrientasyonVertical langVertical, horizontal, grid, cascade
ViewHolderManual na implementasyonSapilitan ayon sa arkitektura
AnimasyonFade transition langDefaultItemAnimator (add, remove, move, change)
Point UpdatesWala (notifyDataSetChanged lang)notifyItemInserted/Removed/Changed
Click listeneronItemClickListener (built-in)Sa pamamagitan ng ViewHolder (walang built-in)
PerformanceSapat para sa listahan hanggang 50 elementoStable na 60 FPS para sa 1000+ elemento

Konklusyon: para sa bagong proyekto gamitin ang RecyclerView. Iwanan ang ListView lamang sa legacy code kung saan ang migration ay hindi makatwirang mahal. Ayon sa mga guideline ng Material Design 3 (2026), ang mga listahan ng anumang kumplikasyon ay dapat gumamit ng RecyclerView upang matugunan ang mga modernong standard ng performance at accessibility.

Mga Madalas Itanong

Ang ListView ba ay luma na o hindi?

ListView ay hindi minarkahan bilang @Deprecated sa Android SDK API 35, ngunit hindi inirerekomenda ng Google ang paggamit nito sa mga bagong proyekto (soft-deprecated). Ang component ay nananatiling gumagana sa lahat ng bersyon ng Android. Ang RecyclerView ay opisyal na kapalit mula 2014. Kung magsisimula ka ng bagong proyekto — piliin ang RecyclerView. Kung nagpapanatili ka ng umiiral na — ang ListView ay patuloy na gagana nang walang pagbabago.

Paano magdagdag ng header/footer sa ListView?

Ang ListView ay sumusuporta sa mga method na addHeaderView(View, Object, boolean) at addFooterView(View, Object, boolean). Ang header at footer ay idinaragdag sa pangkalahatang listahan ng mga elemento, ngunit hindi lumalahok sa adapter — palagi silang ipinapakita sa simula at dulo ng listahan. Mahalaga: idagdag ang header/footer bago itakda ang adapter (setAdapter()), kung hindi ay hindi sila isasaalang-alang. Pagkatapos magdagdag ng header, ang ID ng mga posisyon ng elemento ay lumilipat ng bilang ng mga header.

Bakit hindi nag-scroll ang ListView sa loob ng ScrollView?

ListView at ScrollView parehong nagpoproseso ng vertical gestures, na lumilikha ng conflict: ang panlabas na ScrollView ay humaharang sa scroll, at ang ListView ay hindi nag-scroll. Solusyon: (1) huwag ilagay ang ListView sa loob ng ScrollView — gamitin ang RecyclerView na may NestedScrollingChild, (2) palitan ang ScrollView ng NestedScrollView (API 21+), (3) gamitin ang ListView na may fixed height (android:layout_height="...dp") sa loob ng ScrollView, ngunit sisirain nito ang adaptability.

Paano i-clear ang ListView at i-update ang data?

Ang pag-clear ng data sa ListView ay depende sa uri ng adapter. Para sa ArrayAdapter: adapter.clear() at adapter.addAll(newList) na sinusundan ng adapter.notifyDataSetChanged(). Para sa custom na adapter: i-update ang listahan ng data at tawagan ang notifyDataSetChanged(). Paalala: listView.invalidateViews() ay nagre-redraw lang ng View, ngunit hindi nag-u-update ng data. Palaging baguhin ang data sa pamamagitan ng adapter, hindi direkta.

Paano baguhin ang taas ng elemento ng ListView?

Ang taas ng elemento ng ListView ay itinakda sa item layout. Kung ang layout ay gumagamit ng layout_height="wrap_content", ang taas ay umaayon sa nilalaman. Para sa fixed height ng lahat ng elemento gamitin ang custom na adapter na nagtatakda ng LayoutParams sa getView(): view.layoutParams.height = resources.getDimensionPixelSize(R.dimen.itemHeight). Para sa iba't ibang taas gamitin ang RecyclerView na may iba't ibang view types.

Buod

  • ListView — pangunahing Android SDK component para sa vertical na listahan, available mula API 1.
  • ArrayAdapter — pinakasimpleng adapter para sa listahan ng strings; para sa custom na layout kailangan ng na-override na getView().
  • ViewHolder sa ListView ay ini-implement nang manual sa pamamagitan ng convertView at view.tag — sapilitang kondisyon para sa performance.
  • Ang ListView ay sumusuporta sa choiceMode (single/multiple), header/footer, fastScroll at android:entries nang walang adapter.
  • Mga limitasyon ng ListView: vertical orientation lang, walang animation, kumpletong pag-redraw sa bawat pagbabago.
  • Ang ListView ay hindi minarkahan bilang luma, ngunit inirerekomenda ng Google ang RecyclerView para sa lahat ng bagong proyekto.
  • Para sa listahan hanggang 50 elemento sapat na ang ListView; para sa anumang mas kumplikado — gamitin ang RecyclerView.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din