본문 바로가기

Study/Android

Android : 리스트뷰

개요


이번 포스팅에서 살펴볼 내용은 리스트뷰입니다.

리스트뷰가 무엇인지 우선 안드로이드 개발자 문서에서 확인해보겠습니다.

Displays a vertically-scrollable collection of views, where each view is positioned immediatelybelow the previous view in the list. For a more modern, flexible, and performant approach to displaying lists, use RecyclerView.
To display a list, you can include a list view in your layout XML file:

<ListView
      android:id="@+id/list_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />

쉽게 말해서 사용자가 정의한 데이터 목록을 아이템 단위로 구성하여 화면에 출력해주는 것입니다.


ListItem과 내부 아이템 작성하기


ListItem을 사용하기 위해서 우선 activity_main.xml<ListView>를 작성해줍니다.

TextView는 리스트뷰에서 선택한 아이템을 출력해주기위해 준비해두었습니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            android:textSize="20sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.022"/>
    <ListView
            android:id="@+id/listView"
            android:layout_width="602dp"
            android:layout_height="828dp"
            tools:ignore="MissingConstraints" 
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent" 
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent" 
            app:layout_constraintHorizontal_bias="0.505"
            app:layout_constraintVertical_bias="0.875"/>
</androidx.constraintlayout.widget.ConstraintLayout>

이제 리스트뷰의 각 아이템에 적용해 줄 컴포넌트를 만들어주겠습니다.

<!-- item_spinner.xml -->
<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listItem"
    android:layout_width="match_parent"
    android:layout_height="45dp"
    android:paddingTop="10dp"
    android:paddingStart="30dp"
    android:textColor="@android:color/darker_gray"
    android:textSize="15sp"
    android:paddingLeft="30dp"/>

MainActivity 작성하기


이제 ListItem에 들어갈 각 아이템을 정의해주고 아이템을 클릭할 때마다 텍스트뷰의 내용이 바뀌도록 해주겠습니다.

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.ListView
import android.widget.TextView
import androidx.annotation.Dimension

class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {

    var items = arrayOf(
        "서울", "부산", "대구", "광주", "대전", "울산", "전주", "목포",
        "제주", "강원", "태백", "인천", "서울", "부산", "대구", "광주",
        "대전", "울산", "전주", "목포", "제주", "강원", "태백", "인천",
        "서울", "부산", "대구", "광주",
        "대전", "울산", "전주", "목포", "제주", "강원", "태백", "인천"
    )

arrayOf를 사용하여 배열을 만들어줍니다. 배열 안에 랜덤으로 지명을 넣어주었습니다.


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val listView = findViewById<View>(R.id.listView) as ListView
        val textView = findViewById<TextView>(R.id.textView)
        textView.setTextSize(Dimension.SP, 28.0f)

        // Adapter
        val adapter:ArrayAdapter<*> = ArrayAdapter<Any?>(this, R.layout.item_spinner, items)

        listView.adapter = adapter

        listView.onItemClickListener = this
    }

onCreate 함수에 리스트뷰와 텍스트뷰를 아이디로 하여 접근해주었습니다. 둘 다 main_activity에 있는 컴포넌트들입니다.

val listView = findViewById<View>(R.id.listView) as ListView

자료유형이 확실하지 않을 때 이처럼 제네릭을 <View>로만 써줘도 무방합니다. 다만 as를 사용하여 캐스트 변환을 해줄 수도 있습니다.

textView.setTextSize(Dimension.SP, 28.0f)

텍스트뷰에 표시되는 글자의 크기를 변경해줍니다.
Dimension.SP가 무엇인지 안드로이드 개발자 문서를 참조해보면

Denotes that an integer parameter, field or method return value is expected to represent a dimension.

각각은 DP, PX, SP라는 상수이며 크기를 나타내는 단위입니다.

안드로이드에서는 PX과 같은 절대적인 단위의 사용을 지양하는게 좋습니다.

각각에 대한 참고사항은 여기를 참조해주세요.

우리가 사용할 SP는 시스템 폰트를 반영하라는 것입니다.


    override fun onItemClick(p0: AdapterView<*>?, p1: View?, pos: Int, p3: Long) {
        val textView = findViewById<TextView>(R.id.textView)
        textView.text = items[pos]
    }

}

그 다음으로 onItemClick 함수를 오버라이드 해주었습니다. 각각의 파라미터가 나타내는 것은 다음과 같습니다.

parameter 의미
p0: AdapterView<*>? 클릭이 발생한 AdapterView
p1: View? AdapterView 내에서 클릭한 보기(어댑터에서 제공하는 보기)
pos: Int Adapter에서 View의 위치
p3: Long 클릭된 아이템의 row id

텍스트뷰에는 items 배열의 pos에 해당하는 값을 넣어줍니다.