안녕하세요, 반갑습니다!
안드로이드에는 많은 기능 있습니다.
그 중 아래로 펼쳐지며 메뉴를 보여주는 유용한 기능이 있는데요.
가장 흔하게 보이는 앱이 있다면 사진첩 또는 브라우저가 아닐까 싶습니다.
스피너(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) 를 구현해서 각 항목에 맞는 이미지들을 불러오는 것으로 구현해봤는데요.
이렇게 간단하게 구현할 수 있습니다.
이제 멋진 앱을 만들기만 하면 되겠죠?
감사합니다.