상상하라 그리고 현실로 만들어라.

상상하는 모든 것이 미래다.

Kotlin과 Android/Android

코틀린으로 안드로이드 스피너(Spinner) 한방에 끝내기

월터제이(Walter J) 2020. 11. 10. 09:00

안녕하세요, 반갑습니다!

 

안드로이드에는 많은 기능 있습니다.

그 중 아래로 펼쳐지며 메뉴를 보여주는 유용한 기능이 있는데요.

가장 흔하게 보이는 앱이 있다면 사진첩 또는 브라우저가 아닐까 싶습니다.

 

 

스피너(Spinner)

 

 

어떻게 보면 리싸이클러뷰(RecyclerView) 의 축소판이라고도 할 수 있습니다.

보고 있는 화면을 방해하지 않으면서도 여러 기능을 쓸 수 있도록 다양한 메뉴를 제공,

화면에 즉각 반영될 수 있도록 하는 도구입니다.

 

먼저 .xml 만들어보도록 하겠습니다.

 

1. .xml 파일에 스피너(Spinner) 배치하기

저는 아래처럼 스피너(Spinner)와 이미지 뷰(Image View) 1개를 배치했습니다.

 

그래서 .xml 은 간단히 이렇게 구성됩니다.

<androidx.constraintlayout.widget.ConstraintLayout
    .
    .
    .>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="15dp"
        android:text="게임을 선택하세요"
        app:layout_constraintBottom_toTopOf="@+id/spinner"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
        
    <Spinner
        android:id="@+id/spinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:scaleType="fitStart"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/spinner"
        tools:srcCompat="@tools:sample/avatars" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

2.  스피너(Spinner)에 들어갈 데이터 만들어주기

 

먼저, 스피너(Spinner)는 고정적인 메뉴를 보여주기 때문에, 미리 데이터를 셋팅해 둘 필요가 있습니다.

방법은 2가지가 있습니다.

 

첫 번째, 리스트(List) 배열로 만들기

override fun onCreate(savedInstanceState: Bundle?) {
    .
    .
    .
    
    var data = listOf("선택하세요", "위쳐3", "사이버펑크 2077", "다크소울3", "어쎄신 크리드 발할라")   
} 

이렇게 각 항목의 이름을 배열로 만들어 두는 것입니다.

 

두 번째, 리소스로 만들기

/res/values  아래에 위와 같이 arrays.xml 을 만들어줍니다.

(사실 스피너(Spinner) 의 데이터는 고정적인 메뉴이기 때문에 이렇게 리소스화 해주는 편이 관리적인 측면에서 더 낫습니다.)

 

그리고 이 arrays.xml 파일 안에 데이터를 정의해두면 됩니다.

<resources>
    <string-array name="games">
        <item>선택하세요</item>
        <item>위쳐3</item>
        <item>사이버펑크 2077</item>
        <item>다크소울3</item>
        <item>어쎄신 크리드 발할라</item>
    </string-array>
</resources>

 

그러면 액티비티로 돌아와서 이 데이터를 가져오기만 하면 되는 것이죠.

override fun onCreate(savedInstanceState: Bundle?) {
    .
    .
    .
    
//    var data = listOf("선택하세요", "위쳐3", "사이버펑크 2077", "다크소울3", "어쎄신 크리드 발할라")   
    var sData = resources.getStringArray(R.array.games)
} 

 

3. 스피너(Spinner) 를 위한 어댑터(Adapter) 만들기

스피너(Spinner)는 리싸이클러뷰(RecyclerView) 와 같이 컨테이너를 사용하는 뷰(View)입니다.

 

컨테이너

  • 위젯이나 다른 레이아웃에 데이터를 동적으로 표현해줄 때 사용.
  • 데이터를 반복적으로 표시하는 용도.

 

그래서 마찬가지로 어댑터(Adapter) 를 사용해서 구현하게 됩니다.

 

위에서 데이터도 만들어두었으니 어댑터(Adapter) 를 만들겠습니다.

override fun onCreate(savedInstanceState: Bundle?) {
    .
    .
    .
    var sData = resources.getStringArray(R.array.games)
    var adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, sData)
    spinner.adapter = adapter   
}

 

ArrayAdapter<String>(this, android.R.layout.simple_list_item1, sData).

이 어댑터(Adapter)는 각각의 파라미터를 전달합니다.

  • 스피너(Spinner)가 그려질 컨텍스트,
  • 목록 하나하나의 레이아웃,
  • 각 목록들의 데이터

 

그리고 이 어댑터(Adpater) 를 스피너(Spinner) 에 연결해주기만 하면 끝~

이제 실행하시면 앱에 스피너(Spinner)가 잘 들어가 있는 걸 확인하실 수 있습니다.

 

하지만 이렇게 끝내면 안되겠죠?

어떤 항목이 선택되었는지 알아야하기 때문에 리스너(Listener) 를 연결하겠습니다.

 

4. 스피너(Spinner)의 동작을 감지하는 리스너(Listener) 연결하기

스피너(Spinner) 의 항목이 선택되면 동작하는 리스너(Listener)입니다.

아래와 같이 작성해주세요.

spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {

}

 

작성하고 나면 object 밑에 빨간줄이 생기는데요.

자동완성 기능을 이용해서 Implements methods 를 선택, 나오는 모든 메소드를 선택하시면 됩니다.

spinner.setSelection(1)    //시작 위치를 지정
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
        imgArr.get(position)?.let {  //이미지들을 리스트화 했기 때문에 이렇게 사용했습니다.
            img.setImageResource(it)
        }
    }

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

    }
}

 

위와 같이 onItemSelected() 안에 동작할 코드를 작성해주시면 됩니다.

그리고 각 항목의 위치는 position 으로 전달되므로 이 값을 이용하시면 됩니다.

 

아, 그리고 setSelection() 메소드를 이용해서 시작 위치를 지정해둘 수 있습니다.

그래서 아무것도 선택하지 않아도 빈 화면이 나올 일은 없을 것 같네요.

 

짠! 완성입니다!

 

만들고보니, 사이버 펑크 참 기대중인데.. 언제 어떻게 나올지 기대되네요ㅎㅎ

그리고 발할라는 이제 얼마 안남았습니다.

빨리 나왔으면 좋겠어요ㅎㅎ

 

자, 스피너(Spinner) 를 구현해서 각 항목에 맞는 이미지들을 불러오는 것으로 구현해봤는데요.

이렇게 간단하게 구현할 수 있습니다.

이제 멋진 앱을 만들기만 하면 되겠죠? 

 

 

 

감사합니다.

반응형