TIL - 안드로이드
[안드로이드] Spinner 아이템 선택 안 하고도 onItemSelectedListener 를 타는 문제
cocokaribou
2022. 12. 8. 12:59
스피너 Spinner 를 열지도 않았는데
뷰를 초기화하자마자 디폴트값으로 onItemSelectedListener를 탔다.
검색해보니,
아이템을 선택한 건지 아닌지 판별하기 위해서는
터치리스너를 빼서 플래그를 켜야하는 것 같았다.
Android Spinner OnItemSelected ONLY on User Interaction
I know that this question has been answered multiple times, but I have not found any of them satisfactory and certainly not elegant. The issue is that OnItemSelected gets fired not only when the u...
stackoverflow.com
위의 코드를 정리하자면 이렇다.
spinner.apply {
adapter = ArrayAdapter(binding.root.context, R.layout.view_common_sort_item, list)
setOnTouchListener { _, _ ->
isSpinnerTouched = true
false
}
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (!isSpinnerTouched) return
if (data.selected != parent?.selectedItem) {
// select event
}
isSpinnerTouched = false
}
override fun onNothingSelected(p0: AdapterView<*>?) {
isSpinnerTouched = false
}
}
}
결론:
- 웬만하면 스피너를 쓰지 말자.
- 리사이클러뷰로 뷰를 직접 만들던가 하자.
덧붙이는 말:
스피너는 리사이클러뷰 리스트와 다르게 최상단 UI에 그려진다.
덧붙이는 말 (2023.11):
디폴트로 선택된 아이템이 있다면, 굳이 위처럼 세팅하지 않아도 된다.
itemSelectedListener 를 세팅한 후, setSelection을 호출하면 최초의 선택지를 제어할 수 있다.
// 앱 언어변경 스피너
binding.languageSpinner.apply {
adapter = ArrayAdapter(context, R.layout.view_language_item, languageList)
onItemSelectedListener = itemSelectedListener // 리스너 설정
// 현재 세팅된 언어로 디폴트 선택
setSelection(
when (currentLanguage) {
LOCALE_KOREA -> 0
LOCALE_CHINESE -> 1
else -> 2
}
)
}
이러면 디폴트값으로 onItemSelectedListener을 최초 한 번만 잘 탄다.
728x90