오늘은 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
}
}
'기리's Android 이야기' 카테고리의 다른 글
[Android/Kotlin] 안드로이드 Spinner 커스텀 해보기(1) (4) | 2021.01.30 |
---|---|
[Android Studio/Kotlin] 안드로이드 Live Template 사용하기 (2) | 2021.01.26 |
[Android/Kotlin] 안드로이드 뒤로가기 종료 방지하기 feat. onBackPressed() (0) | 2021.01.23 |
[Android/Kotlin] 안드로이드 Single Click 구현하기 feat. 두번 클릭 방지... (2) | 2021.01.22 |
[Android/Error] 안드로이드 Caused by: java.lang.NullPointerException: Missing required view with ID: ~~~~~ (3) | 2021.01.21 |