Archives
Recent Posts
«   2025/02   »
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 26 27 28
Today
Total
관리 메뉴

안드로이드 개발자의 창고

[31일차 Android] ListView - ArrayAdapter 본문

Computer/Android

[31일차 Android] ListView - ArrayAdapter

Wise-99 2023. 6. 14. 18:22

 

 

 

출처 : 안드로이드 앱스쿨 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을 적용시킨다.