안드로이드의 ListView는 스크롤 가능한 목록을 표시하는 데 사용되는 뷰 그룹으로써, ListView는 동일한 형식의 항목을 반복적으로 보여주는 데 적합하며, List형태의 데이터를 대량의 데이터를 효율적으로 처리할 수 있다.
위의 구조에서도 봤듯이 리스트뷰에서 데이터를 뿌려 주기 위해서는 Adapter가 필요하다. Adapter는 리스트 형태의 데이터를 받아와 항목에 대한 데이터를 이용하여 뷰를 생성해주는 역할을 한다. 말로 설명해서 이해하기 보다는 직접 구현 해보며 알아 보자.
구현하는 방법 또는 구현하는 순서 같은 경우 여러가지가 있겠지만 내가 가장 익숙하게 사용했던 방법을 순서대로 정리해 보자.
data class ListViewModel(
val title : String = "",
val content : String = ""
)
class ListViewPracticeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_list_view_practice)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
val items = mutableListOf<ListViewModel>()
items.add(ListViewModel("맘스터치","싸이버거"))
items.add(ListViewModel("롯데리아","크리스피버거"))
items.add(ListViewModel("맥도날드","베이컨토마토디럭스"))
val listView : ListView = findViewById(R.id.lv)
listView.adapter = ListViewAdapter(items, this)
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:text="title"
android:textSize="20sp"
android:id="@+id/itemTitle"
android:layout_width="wrap_content"
android:layout_height="60dp"/>
<TextView
android:text="content"
android:layout_marginLeft="10dp"
android:textSize="15sp"
android:id="@+id/itemContent"
android:layout_width="wrap_content"
android:layout_height="60dp"/>
</LinearLayout>
class ListViewAdapter(val items : MutableList<ListViewModel>, val context : Context) : BaseAdapter(){
override fun getCount(): Int {
return items.size
}
override fun getItem(position: Int): Any {
return items[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getView(position: Int, convertView : View?, parent: ViewGroup?): View {
var view = convertView
if(view == null) {
view = LayoutInflater.from(parent?.context).inflate(R.layout.lv_item,parent,false)
}
view!!.setOnClickListener{
Toast.makeText(context,"${items[position].title.toString()} : ${items[position].content.toString()}",Toast.LENGTH_LONG).show()
}
var title : TextView = view!!.findViewById(R.id.itemTitle)
val content : TextView = view!!.findViewById(R.id.itemContent)
title.text = items[position].title
content.text = items[position].content
return view!!
}
}
리스트뷰의 Adapter에서 context를 함께 파라미터로 받아오면 아이템 클릭에대한 event를 구현할 수 있다. 간단하게 해당 아이템에 대한 정보를 Toast로 띄웠다.
ListView는 모든 아이템을 불러오기 때문에, 스크롤 시에도 모든 아이템을 유지하며 화면에 보여준다. 따라서 성능 적인 부분도 떨어지고, 레이아웃 관리등 유연성이 부족하기 때문에 복잡한 기능과 성능 최적화가 필요한 경우는 ListView 보다는 RecyclerView를 사용하는 것이 바람직하다.