addView
addView는 지정한 Layout에 동적으로 View를 추가할 수 있는 메서드입니다.
여기서 addView를 사용하는 방법에는 두 가지가 있습니다.
- 코드 상에서 View를 만들어 레이아웃에 추가하는 방식
- 리스트뷰의 아이템을 담을 xml을 직접 만들어 추가하는 방식
1. 리스트뷰를 담을 container 생성
addView 방식은 자동으로 스크롤이 추가되지 않기 때문에 container를 ScrollView로 감싸주어야 합니다.
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
2-1. 코드 상에서 View를 만들어 레이아웃에 추가하는 방식
직접 TextView를 코드로 짜서 addView를 통해 레이아웃에 추가합니다.
val container = binding.linearLayout
TextView(this).apply {
textSize = 20f
gravity = Gravity.CENTER
text = container.childCount.inc().toString() // 1, 2, 3, ...
}.let {
container.addView(it, 0)
}
2-2. 리스트뷰의 아이템을 담을 xml을 직접 만들어 추가하는 방식
Item을 담을 xml을 만들고 Activity에서 Item List를 만들어 addView를 통해 레이아웃에 추가합니다.
<?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="match_parent"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/tv_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" />
<TextView
android:id="@+id/tv_dot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:text="."
android:textSize="20sp" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" />
</LinearLayout>
// Item List 만들기
val fruitList = mutableListOf<String>()
fruitList.add("사과")
fruitList.add("복숭아")
fruitList.add("파인애플")
val container = binding.linearLayout
val inflater = LayoutInflater.from(this)
for (i in 0 until fruitList.size) {
// inflater로 item_view.xml 객체화
val itemView = inflater.inflate(R.layout.item_fruit, null)
// 아이템 뷰에 내용 추가
val tvCount = itemView.findViewById<TextView>(R.id.tv_count)
val tvName = itemView.findViewById<TextView>(R.id.tv_name)
tvCount.text = (i + 1).toString()
tvName.text = fruitList[i]
// container에 아이템 뷰 추가하기
container.addView(itemView)
}
ListView
ListView는 일반적으로 리스트 형태로 화면에 표시하는 뷰 그룹의 한 종류입니다.
ListView에서는 Adapter를 통해 여러 개의 아이템을 관리합니다.
1. ListView를 담을 container 생성
<ListView>를 이용합니다.
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
2. ListView의 아이템을 담을 xml 생성 및 Item List 만들기
addView 방식과 동일합니다.
3. 아이템을 관리할 Adapter 생성
- ListView의 성능을 향상시키기 위해 ViewHolder를 이용합니다.
- 리스트에 item이 많은 경우, getView()에서 findViewById()를 많이 호출하기 때문에 시스템에 과부하가 걸릴 수가 있습니다. 따라서, 뷰를 뷰 홀더에 담아놓고 재사용하는 방법을 이용해서 ListView의 성능을 향상시킵니다.
- convertView(재활용되는 view)는 최초 한번만 생성됩니다. 따라서, 최초로 호출되는 getView()의 convertView는 null인 특성을 이용해서 convertView가 null인 경우에만 레이아웃을 inflate하고 그 레이아웃 안에 있는 view들을 findViewById()로 찾아 ViewHolder에 저장하여 그 홀더를 tag에 저장합니다.
- 최초 이후에 호출되는 getView()의 경우에는 이미 만들어진 view를 tag를 통해 불러와서 사용하기 때문에 view를 재사용하면서 성능이 좋아집니다.
class ListViewAdapter(
private val fruitList: MutableList<String>
) : BaseAdapter() {
inner class FruitViewHolder {
var fruitCount: TextView? = null
var fruitName: TextView? = null
}
override fun getCount(): Int {
return fruitList.size
}
override fun getItem(position: Int): Any {
return fruitList[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View? {
var view = convertView
val viewHolder: FruitViewHolder
// 재사용할 뷰가 없다면
if (convertView == null) {
// 레이아웃 inflate
view = LayoutInflater.from(parent?.context).inflate(R.layout.item_fruit, parent, false)
// viewHolder 생성
viewHolder = FruitViewHolder()
// inflate한 레이아웃 안에 있는 뷰를 viewHolder에 넣는다
viewHolder.fruitCount = view.findViewById(R.id.tv_count)
viewHolder.fruitName = view.findViewById(R.id.tv_name)
// tag에 viewHolder를 저장한다
view.tag = viewHolder
} else {
// tag로 뷰를 불러와서 대체한다
viewHolder = convertView.tag as FruitViewHolder
}
viewHolder.fruitCount?.text = (position + 1).toString()
viewHolder.fruitName?.text = fruitList[position]
return view
}
}
// Adapter 연결하기
val listView = binding.listView
listView.adapter = ListViewAdapter(fruitList)
addView vs ListView
- addView에서는 리스트 안 아이템의 개수와 상관 없이 모두 한번에 그립니다.
- ListView에서는 보여지는 부분 + α를 한번에 그리고, 필요한 경우에 더 그립니다.
- 예를 들어, 리스트에 아이템이 많아서 한 화면 안에 모든 아이템을 담지 못하는 경우에는 일단 현재 화면에 띄울 수 있는 부분만 그려놓고 나중에 스크롤을 내렸을 때 다른 부분을 더 그립니다.
- 또한, ListView는 addView 방식과는 다르게 기본으로 구분선(divider)을 가지고 있습니다.
728x90
반응형
'안드로이드 > 활용' 카테고리의 다른 글
[Android] ListAdapter로 RecyclerView 효율적으로 사용하기 (0) | 2023.07.27 |
---|---|
[Android] RecyclerView (0) | 2023.07.26 |
[Android] Room 사용하기 (0) | 2023.07.24 |
[Android] SQLite 사용하기 (0) | 2023.07.24 |
[Android] 로컬 데이터베이스에 데이터 저장 (0) | 2023.07.22 |