본문 바로가기

[Android/Kotlin] 안드로이드 ArrayAdapter를 활용한 Spinner 구현

꿈꾸는블로그왕 2021. 1. 25.

오늘은 Spinner 위젯을 사용해서 아이템 리스트를 구현하고 사용자 선택하도록 하는 방법을 알아보겠습니다.

 

Drop Down Menu라고 해서 Spinner를 클릭하면 아래로 메뉴 목록이 나타나고, 아이템을 클릭하면 어떠한 이벤트가 발생하도록 할 수 있습니다.

 

사용자가 연도와 월을 선택할 수 있는 화면을 만들어 보겠습니다.

 

완성된 모습은 아래와 같습니다.

 

 

 

STEP01. 기본 레이아웃 만들기

[activity_main.xml]

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    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"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">
        
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp"
            android:text="Year"
            android:textSize="20sp"
            android:textStyle="bold" />

        <Spinner
            android:id="@+id/spinner_year"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end" />

        <TextView
            android:id="@+id/txt_year"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingVertical="8dp"
            android:paddingHorizontal="16dp"
            android:text="Selected: "
            android:textAlignment="textEnd"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp"
            android:text="Month"
            android:textSize="20sp"
            android:textStyle="bold" />

        <Spinner
            android:id="@+id/spinner_month"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end" />

        <TextView
            android:id="@+id/txt_month"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingVertical="8dp"
            android:paddingHorizontal="16dp"
            android:text="Selected: "
            android:textAlignment="textEnd"/>

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

STEP02. Spinner 값 만들기

레이아웃에 스피너를 포함했지만 아직 스피너에 아무 값도 들어 있지 않은 상태입니다.

스피너에 값을 넣기 위해서 문자열 배열이 필요합니다. 여기에는 다음 두가지 방법으로 문자열 배열을 만들어 보도록 하겠습니다.

 

1) string-array 활용

strings.xml 파일 아래와 같이 string-array를 추가해 줍니다.

<resources>
    <string name="app_name">SpinnerExample</string>

    <string-array name="spinner_year">
        <item>2021</item>
        <item>2020</item>
        <item>2019</item>
        <item>2018</item>
        <item>2017</item>
        <item>2016</item>
        <item>2015</item>
    </string-array>
</resources>

사용 할때는 아래와 같이 사용할 수 있습니다.

val years = resources.getStringArray(R.array.spinner_year)

 

2) 배열 사용하기

month을 담고 있는 문자열 배열을 아래와 같이 만들어 줍니다.

val months = DateFormatSymbols().months

 

 

STEP03. ArrayAdapter로 연결하기

ArrayAdapter는 배열을 뷰에 연결하도록 도와주는 어댑터입니다. 

ArrayAdapter를 초기화 하려면 세가지가 필요합니다. 1) Context, 2) 배열의 각 항목을 어떻게 표시할 지 지정하는 레이아웃 3) 배열 이렇게 세가지 입니다.

private fun setupSpinnerYear() {
    val years = resources.getStringArray(R.array.spinner_year)
    val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, years)
    binding.spinnerYear.adapter = adapter
}

private fun setupSpinnerMonth() {
    val months = DateFormatSymbols().months
    val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, months)
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
    binding.spinnerMonth.adapter = adapter
}

setAdapter()를 호출하여 ArrayAdapter를 Spinner에 연결합니다.

 

 

STEP04. onItemSelectedListener로 이벤트 받기

사용자가 Spinner의 항목을 선택할 때 발생하는 이벤트입니다.

해당 리스너를 구현하여 사용자가 선택한 항목을 가져올 수 있습니다.

private fun setupSpinnerHandler() {
    binding.spinnerYear.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
            binding.txtYear.text = "Selected: ${binding.spinnerYear.getItemAtPosition(position)}"
        }

        override fun onNothingSelected(p0: AdapterView<*>?) {

        }
    }

    binding.spinnerMonth.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
            binding.txtMonth.text = "Selected: ${binding.spinnerMonth.getItemAtPosition(position)}"
        }

        override fun onNothingSelected(p0: AdapterView<*>?) {

        }
    }
}

오버라이드한 onItemSelected() 메소드에서 position을 가지고 Spinner의 해당하는 값을 가져옵니다.

 

 

아래는 액티비티 전체 코드입니다.

[MainActivity.kt]

class MainActivity : AppCompatActivity() {

    private var _binding: ActivityMainBinding? = null
    private val binding get() = _binding!!

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        _binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        setupSpinnerYear()
        setupSpinnerMonth()
        setupSpinnerHandler()
    }

    private fun setupSpinnerYear() {
        val years = resources.getStringArray(R.array.spinner_year)
        val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, years)
        binding.spinnerYear.adapter = adapter
    }

    private fun setupSpinnerMonth() {
        val months = DateFormatSymbols().months
        val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, months)
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        binding.spinnerMonth.adapter = adapter
    }

    private fun setupSpinnerHandler() {
        binding.spinnerYear.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                binding.txtYear.text = "Selected: ${binding.spinnerYear.getItemAtPosition(position)}"
            }

            override fun onNothingSelected(p0: AdapterView<*>?) {

            }
        }

        binding.spinnerMonth.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                binding.txtMonth.text = "Selected: ${binding.spinnerMonth.getItemAtPosition(position)}"
            }

            override fun onNothingSelected(p0: AdapterView<*>?) {

            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        _binding = null
    }
}

댓글