본문 바로가기

Programming/Android_Kotlin

Spinner에 데이터 연동하기

처음 Playstore에 등록했던 앱인 g to mL 변환기에서 변환 대상 항목을 설정하기 위한 View로 Spinner를 채택했다. 많은 공간을 차지하지 않고 다양한 항목을 보여줄 수 있어 다양한 용도로 활용이 가능하다.

 

우선 layout의 xml 파일에 Spinner를 추가해주자.

 

<Spinner
  android:id="@+id/itemSpinner"
  android:layout_width="0dp"
  android:layout_height="wrap_content" />

 

여기서 spinnerMode 항목을 비워두거나 dropdown으로 지정하면 드롭다운 메뉴, dialog로 지정하면 팝업 형식의 다이얼로그로 표시된다.

◀ dropdown / dialog ▶

Spinner를 넣기만 하면 기능은 정상적으로 작동한다. 나머지는 데이터를 넣어주기만 하면 되는데 두 가지 방법이 있다.


1. xml에서 직접 넣어주기

res/values/arrays.xml 파일에 string-array resource를 넣어놓고 layout xml에서 직접 불러와 연동하는 방식이다.

우선 values 폴더 내에 arrays.xml 파일을 만들어 데이터를 입력한다.

 

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="units">
    	...
        <item>계란</item>
        <item>계란 노른자</item>
        <item>계란 흰자</item>
        ...
    </string-array>
</resources>

 

그리고 앞에서 넣어준 spinner의 entries Attribute에서 해당 array를 넣어주면 된다.

 

 

이렇게 하면 arrays.xml에서 units라는 이름의 string-array를 읽어와 spinner에 표시해준다. 하지만 내가 제작한 g to mL앱의 경우 다국어를 지원해야했기 때문에 해당 방법을 사용하면 'ABC순', '가나다순' 등 언어별 정렬이 조금 곤란해진다. 따라서 정렬처럼 array의 가공이 필요한 경우는 아래 방법으로 넣으면 된다.


2. 코드에서 넣어주기

코드에서 넣는 방법은 해당 스피너의 어댑터에 ArrayAdapter를 생성하여 넣어주면 된다.

 

...
  /* 리스트 가공 */
  val itemList = resources.getStringArray(R.array.units)
  itemList.sort()
  /* 리스트 가공 */

  itemSpinner.adapter = ArrayAdapter(this, R.layout.support_simple_spinner_dropdown_item, itemList)
...

 

다른 부분은 리스트를 불러와 가공하는 부분이고, 중요한 것은 가장 아래 Spinner에 adapter를 붙이는 부분이다. 해당 코드가 실행되면 가공된 리스트가 입력돼 표시되는 것을 볼 수 있다.


리스너 연결하기

스피너는 선택된 항목이 변경될 때마다 함수가 실행되도록 리스너를 연결할 수 있다. 아래와 같이 코드를 짜면 선택된 항목의 앞 글자가 '계란' 혹은 'egg'인지 검사하여 View를 표시하는 기능을 수행한다.

 

itemSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                try {
                    if (itemSpinner.getItemAtPosition(position).toString().substring(0, 2) == "계란" ||
                        itemSpinner.getItemAtPosition(position).toString().substring(0, 3) == "egg")
                        eggAlert.visibility = View.VISIBLE
                    else eggAlert.visibility = View.GONE
                } catch(e: Exception) {
                    Log.d("MainActivity", e.toString())
                    eggAlert.visibility = View.GONE
                }
                convertedText.setText("0")
            }

            override fun onNothingSelected(p0: AdapterView<*>?) = Unit
        }

 

스피너의 onItemSelectedListener에 AdapterView.OnItemSelectedLinstener 객체를 생성하여 넣어준다. 해당 객체의 onItemSelected() 함수를 override하여 선택된 아이템에 대해 처리할 연산을 지정해주고, onNothingSelected() 함수를 override하면 아무것도 선택하지 않고 취소했을 때 수행할 연산을 지정해줄 수 있다.


참고자료

https://kkgram.tistory.com/14