[android : kotlin] 코틀린 커스텀 리스트 뷰( Custom ListView ) 사용 예제
리스트뷰(ListView)는 여러 항목들을 제공하고, 스크롤 가능한 항목을 나타낼 때 사용되는 뷰 그룹이다. ListView에 먼저 View를 배치 후 데이터를 View의 형식에 맞게 변환하여 가져온다. 리스트뷰를 구성하기 위해서는 adapter(어댑터) 객체를 생성 후 설정해야한다. OnItemClickListener()는 리스트뷰의 항목을 클릭했을때 반응하는 이벤트 리스너이다.
커스텀 리스트 뷰를 사용해야하는 경우는 첫 번째로 기본적으로 지원하는 simple_list_item_1.xml의 텍스트뷰를 개발자가 원하는 글씨크기와 색상등을 변경하고자 할 때 사용된다. 두 번째는 항목이 하나가 아닌 여러개의 항목(데이터)을 리스트 뷰로 보여주기 위해서 사용된다.
[MainActivity.kt]
package edu.kotlin.study
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.*
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
var dataArr = arrayOf("사괴", "복숭아", "오렌지", "자두")
var dataArr2 = arrayOf("apple", "peach", "orange", "plum")
var imgArr = intArrayOf(
R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_foreground
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//기본적인 리스트뷰 사용방법
//var simpleListAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, dataArr)
//listview1.adapter = simpleListAdapter
var list = ArrayList<HashMap<String, Any>>()
var idx = 0
while (idx < dataArr.size) {
var map = HashMap<String, Any>()
map.put("img", imgArr[idx])
map.put("kor", dataArr[idx])
map.put("eng", dataArr2[idx])
list.add(map)
idx++
}
var keys = arrayOf("img", "kor", "eng")
var ids = intArrayOf(R.id.imageView, R.id.textView1, R.id.textView2)
//커스텀 리스트뷰 사용법
// var customAdapter =
// ArrayAdapter(this, R.layout.custom_simple_list_item_1, R.id.textView2, dataArr)
// listview1.adapter = customAdapter
//커스텀 리스트뷰 사용법2
var customAdapter2 =
SimpleAdapter(this, list, R.layout.custom_simple_list_item_1, keys, ids)
listview1.adapter = customAdapter2
//중첩함수를 사용하는 방법
var listener = SimpleListListener()
listview1.onItemClickListener = listener
//람다식 사용 : 오버라이드해야할 메서드가 1개 임으로 가능하다.
listview1.setOnItemClickListener { parent, view, position, id ->
textView1.text = dataArr[position]
}
}
inner class SimpleListListener : AdapterView.OnItemClickListener {
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
textView1.text = dataArr[position]
}
}
}
[activity_main.xml]
<?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="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="리스트뷰"
android:textAppearance="@style/TextAppearance.AppCompat.Display2" />
<ListView
android:id="@+id/listview1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
[custom_simple_list_item_1.xml]
<?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:gravity="center|left"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_launcher_foreground" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="아이템"
android:textColor="@color/colorPrimary"
android:textAppearance="@style/TextAppearance.AppCompat.Display2" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="아이템2"
android:textColor="@color/colorPrimary"
android:textAppearance="@style/TextAppearance.AppCompat.Display2" />
</LinearLayout>
</LinearLayout>
[build.gradle(:app)]
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
defaultConfig {
applicationId "edu.kotlin.study"
minSdkVersion 22
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
ListView는 Adapter를 통해 getView 메서드를 호출하여 View를 만든다. 최초로 화면을 로딩한 후에도 스크롤을 움직이는 등 액션을 취하면 그 때마다 findViewById를 통해 convertView에 들어갈 요소를 찾기 때문에 리소스를 많이 사용하게 되고 속도가 느려지는 단점을 가지고 있다. 리스트 뷰의 단점을 보완하기 위해 리사이클러뷰(RecyclerView)가 지원됨으로 되도록이면 리스트뷰의 사용 보다는 리사이클러뷰의 사용을 추천한다.