안드로이드 개발자의 창고
[31일차 Android] ListView - ArrayAdapter 본문
출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 PPT
📖 Adapter View
- 개발자는 화면의 다양한 View들을 배치해 화면을 구성하게 된다.
- 대부분의 뷰들은 배치를 하면 기본적으로 정해진 속성에 따라 모양이 구성된다.
- 하지만 일부 View들은 스스로 결정할 수 없는 부분이 있어 개발자가 반드시 데이터를 설정해야만 구성이 가능하다.
- 이렇게 개발자가 반드시 설정해야 화면을 구성할 수 있는 View들을 가르켜 Adapter View라고 부른다.
Adapter Class
- Adapter View들은 View 구성하기 위해서 개발자가 다양한 데이터를 설정해줘야 한다.
- 이러한 데이터를 관리하는 Class 를 Adapter Class라고 부른다.
- Adapter Class는 사용 목적이나 적용할 View 에 따라 다양하게 제공되고 있으며 원한다면 직접 생성해서 사용할 수도 있다.
- 주로 다양한 항목을 제공하는 View를 구성할 때 사용한다.
📖 ListView
- RecyclerView 사용을 추천하고 있지만 AdapterView 개념을 공부하기에 적당한 View
주요 프로퍼티
프로퍼티 | 설명 |
adapter | AdapterView를 구성하기 위해 사용하는 adapter를 관리 |
주요 이벤트
이벤트 | 설명 |
ItemClick | 항목을 터치하면 발생 |
📖 예제 코드
예제 코드1 - 데이터가 정해져 있는 ListView
activity_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MainActivity.kt
package com.test.android28_listview
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import com.test.android28_listview.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var activityMainBinding: ActivityMainBinding
// ListView를 구성하기 위해 필요한 데이터
val data1 = arrayOf(
"문자열1", "문자열2", "문자열3", "문자열4", "문자열5",
"문자열6", "문자열7", "문자열8", "문자열9", "문자열10",
"문자열11", "문자열12", "문자열13", "문자열14", "문자열15",
"문자열16", "문자열17", "문자열18", "문자열19", "문자열20",
"문자열21", "문자열22", "문자열23", "문자열24", "문자열25"
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding.root)
val adapter = ArrayAdapter<String>(
this, android.R.layout.simple_list_item_1, data1
)
activityMainBinding.run{
listView.run{
setAdapter(adapter)
setOnItemClickListener { parent, view, position, id ->
textView.text = "${data1[position]}를 눌렀습니다"
}
}
}
}
}
코드 리뷰
- ArrayAdapter
- 항목 하나에 문자열 하나만 사용하는 경우에 ArrayAdapter를 사용하여 adapter를 생성한다.
- 첫번째 매개 변수로 context, 두번째 매개 변수로 layout 파일, 세번째 매개 변수로 데이터를 넣은 리스트를 설정한다.
- Context
- 어떠한 작업을 위한 정보를 관리하는 요소들을 통칭한다.
- 안드로이드는 시스템이나 애플리케이션과 관련된 정보를 가지고 있다.
- 해당 코드에서 context는 this@MainActivity이다.
- android.R.layout.simple_list_item1 : 안드로이드에서 리스트뷰의 항목 하나를 구성할 때 사용하라고 제공하는 layout
- setAdapter(adapter) : ListView에 adapter를 설정한다.
- setOnItemClickListener { ... }
- ListView의 항목 하나를 선택하면 동작하는 리스너
- position : 사용자가 터치한 항목의 순서 값(0부터 1씩 증가)
예제 코드2 - 데이터를 추가, 삭제하는 ListView
activity_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="항목개수 : 0개"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MainActivity.kt
package com.test.android29_addadapterviewitem
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import com.test.android29_addadapterviewitem.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var activityMainBinding: ActivityMainBinding
// 데이터가 없는 리스트를 만든다.
val rowList = mutableListOf<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding.root)
activityMainBinding.run {
listView.run {
adapter = ArrayAdapter<String>(
this@MainActivity, android.R.layout.simple_list_item_1, rowList
)
}
button.run {
setOnClickListener {
// 현재 시간을 밀리 세컨드 단위로 반환함
val str1 = "row : ${System.currentTimeMillis()}"
rowList.add(str1)
textView.text = "항목 개수 : ${rowList.size}개"
val adapter = listView.adapter as ArrayAdapter<String>
adapter.notifyDataSetChanged()
}
}
button2.run {
setOnClickListener {
rowList.removeLast()
textView.text = "항목 개수 : ${rowList.size}개"
val adapter = listView.adapter as ArrayAdapter<String>
adapter.notifyDataSetChanged()
}
}
}
}
}
코드 리뷰
- button.run { ... }
- rowList.add(str1) : Adapter를 구성하기 위해 사용하는 list에 데이터를 추가한다.
- adapter.notifyDataSetChanged() : listView의 adapter를 통해 갱신을 요청한다.
- button2.run { ... }
- rowList.removeLast() : rowList의 마지막 요소를 제거한다.
예제 코드3 - layout 파일을 직접 만들어 적용한 ListView
row.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="horizontal">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
</LinearLayout>
activity_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MainActivity.kt
package com.test.android30_customitemview1
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import com.test.android30_customitemview1.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var activityMainBinding: ActivityMainBinding
// ListView를 구성하기 위해 필요한 데이터
val data1 = arrayOf(
"문자열1", "문자열2", "문자열3", "문자열4", "문자열5",
"문자열6", "문자열7", "문자열8", "문자열9", "문자열10",
"문자열11", "문자열12", "문자열13", "문자열14", "문자열15",
"문자열16", "문자열17", "문자열18", "문자열19", "문자열20",
"문자열21", "문자열22", "문자열23", "문자열24", "문자열25"
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding.root)
activityMainBinding.run {
listView.run{
adapter = ArrayAdapter<String>(
this@MainActivity, R.layout.row, R.id.textView2, data1
)
setOnItemClickListener { adapterView, view, i, l ->
textView.text = data1[i]
}
}
}
}
}
코드 리뷰
- adapter = ArrayAdapter<String>( ... )
- R.layout.row를 두번째 매개 변수로 지정하여 직접 만든 layout을 적용시킨다.
'Computer > Android' 카테고리의 다른 글
[32일차 Android] ListView - CustomAdapter (0) | 2023.06.15 |
---|---|
[31일차 Android] ListView - SimpleAdapter (0) | 2023.06.15 |
[31일차 Android] FloatingActionButton (0) | 2023.06.14 |
[31일차 Android] CardView (0) | 2023.06.14 |
[30일차 Android] Bar(ProgressBar, SeekBar, RatingBar) (0) | 2023.06.14 |