안드로이드

[안드로이드] ListView 구현하기(Kotlin)

디벨로펄 2022. 10. 2.
반응형

안드로이드에서 리스트 뷰 대신, Recycler뷰를 사용하기를 권장한다고 한다. 

일단 Recycler뷰를 구현하기 전 단계로 ListView를 구현해보자.

 

ListView를 구현하기 전에 먼저 Adapter라는게 뭔지 한 번 알아보자.

 

- Adapter : Data를 View로!

어댑터

어댑터는 위 그림에서와 같이 Data를 UI 상에 표현하는 역할을 한다.

하나의 data를 하나의 ListView Item으로 변환하는 것이다.

 

- ListView 구현 준비물

1. ListView를 포함하고 있는 Layout(xml)

layout

list View에 id만 잘 붙여주면 되겠다.

<ListView
    android:id ="@+id/lv_book"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="15dp"
    android:layout_marginRight="15dp"
    android:layout_marginBottom="20dp" />

2. listView item Layout(xml파일)

 

listView Item

 

더보기

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="5dp"
    android:layout_marginTop="5dp"
    android:layout_marginRight="5dp"
    android:layout_marginBottom="5dp"
    android:gravity="center_vertical"
    android:layoutDirection="ltr">

    <ImageView
        android:id="@+id/lv_Img_item_event"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:contentDescription="@string/main_lv_event"
        app:srcCompat="@drawable/ic_account_circle_24" />

    <LinearLayout
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/lv_item_name"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            android:text="@string/main_lv_name"
            android:textColor="#000000"
            android:textSize="20sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/lv_item_detail"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:text="@string/main_lv_detail"
            android:textSize="20sp" />
    </LinearLayout>

    <TextView
        android:id="@+id/lv_item_money"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/main_lv_money"
        android:textColor="#0B0B0B"
        android:textSize="20sp"
        android:textStyle="bold" />
</LinearLayout>

3. Adapter

아래 코드가 핵심이다. getView에서 실제 보여지는 List의 Item을 생성한다.

override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup?): View {
    // layout inflater는 item을 adapter에 사용할 view로 만들어준다.
    val view: View = LayoutInflater.from(context).inflate(R.layout.main_lv_item, null)

    val name = view.findViewById<TextView>(R.id.lv_item_name)
    val detail = view.findViewById<TextView>(R.id.lv_item_detail)
    val amount = view.findViewById<TextView>(R.id.lv_item_money)
    val item = listViewItems[position]
    name.text= item.name
    val detailTxt= item.event+"/"+item.date
    detail.text= detailTxt

    val amountTxt :String = if(item.amount>0){
        item.amount.toString()+"원"
    }else{
        "-"+item.amount+"원"
    }
    amount.text = amountTxt
   return view
}

이 과정이 일어난다.

더보기
package com.example.eventmoneymanager

import android.content.Context
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import com.example.eventmoneymanager.dataclass.ListViewData


class ListViewAdapter(val context:Context) : BaseAdapter() {
    private var listViewItems = mutableListOf<ListViewData>()
    override fun getCount(): Int {
        return listViewItems.size
    }

    override fun getItem(p0: Int): Any {
        return listViewItems[p0]
    }

    override fun getItemId(p0: Int): Long {
        return listViewItems[p0].hashCode().toLong()
    }

    fun setItems(items:MutableList<ListViewData>){
        this.listViewItems= items
    }

    fun addItem(item:ListViewData){
        this.listViewItems.add(item)
    }

    override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup?): View {
        // layout inflater는 item을 adapter에 사용할 view로 만들어준다.
        val view: View = LayoutInflater.from(context).inflate(R.layout.main_lv_item, null)

        val name = view.findViewById<TextView>(R.id.lv_item_name)
        val detail = view.findViewById<TextView>(R.id.lv_item_detail)
        val amount = view.findViewById<TextView>(R.id.lv_item_money)
        val item = listViewItems[position]
        name.text= item.name
        val detailTxt= item.event+"/"+item.date
        detail.text= detailTxt

        val amountTxt :String = if(item.amount>0){
            item.amount.toString()+"원"
        }else{
            "-"+item.amount+"원"
        }
        amount.text = amountTxt
       return view
    }
}

 

실제 데이터를 넣는 코드는 다음과 같다. 테스트용

// list뷰 관리.
val list = mutableListOf<ListViewData>()
list.add(ListViewData("DAVID","생일","2021.04.01",100000, listOf("b","d","e")))
list.add(ListViewData("TOD","생일","2021.10.25",10000, listOf("b","d","e")))
list.add(ListViewData("TORES","결혼식","2023.11.25",150000, listOf("b","d","e")))
list.add(ListViewData("GABIEL","생일","2022.01.01",180000, listOf("b","d","e")))

val listView = binding.lvBook
val adapter = context?.let { ListViewAdapter(requireContext()) }
listView.adapter=adapter
adapter?.setItems(list)

 

결과

 

리사이클러뷰의 경우 ViewHolder를 따로 구현해주어야한다. 해당 내용에 대해서 이어서 구현해보도록 해야겠다.

 

반응형

댓글