티스토리 뷰
Spinner의 동적 구조는 다음과 같다.
주소1(도,광역시) 변경 -> 주소2(시,군,구) 변경 -> 주소3(동,면) 변경
주소1이 변경되면 주소1의 값을 기준으로 주소2는 서버로부터 주소를 받아온다. 그리고 주소3은 주소2의 변경을 감지하고 서버로부터 주소를 받아온다.
하지만 여기서 주의할 점이 있다. 바로 '전체 주소'의 존재이다. 예를들어 경기도(주소1) 전체에서 검색을 하고 싶을 경우 하위 주소(주소2,주소3)은 말그대로 '전체'로 설정이 되어야 한다.
이 '전체'를 서버로 부터 받아오지 않고(서버는 본래 목적에 맞게 실질적인 주소들만 반환한다), Viewmodel에서 받아온 값에 추가하기로 설정했다.
XML
onItemSelected eventListener -> onSpinnerItemSelectedAddr
<RelativeLayout
android:layout_marginTop="50dp"
android:layout_width="400dp" android:layout_height="200dp"
android:orientation="horizontal"
android:visibility="@{vm.visiblityOfRegion? View.VISIBLE:View.GONE}"
>
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal">
<Spinner
android:id="@+id/addr1"
android:layout_width="110dp"
android:background="@drawable/spinner_background"
android:layout_marginTop="10dp"
android:layout_centerHorizontal="true"
android:layout_height="wrap_content"
android:onItemSelected="@{vm::onSpinnerItemSelectedAddr1}"
/>
<Spinner
android:id="@+id/addr2"
android:layout_width="110dp"
android:background="@drawable/spinner_background"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"
android:layout_centerHorizontal="true"
android:layout_height="wrap_content"
android:onItemSelected="@{vm::onSpinnerItemSelectedAddr2}"
/>
<Spinner
android:id="@+id/addr3"
android:layout_width="110dp"
android:background="@drawable/spinner_background"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"
android:layout_centerHorizontal="true"
android:layout_height="wrap_content"
android:onItemSelected="@{vm::onSpinnerItemSelectedAddr3}"
/>
</LinearLayout>
<Button
android:id="@+id/button4"
android:layout_width="100dp"
android:layout_height="40dp"
android:layout_marginLeft="145dp"
android:layout_marginTop="100dp"
android:text="검색"
android:onClick="@{()->vm.getMarkerByRegion()}"/>
</RelativeLayout>
ViewModel
주소1의 값(addr1Entry)은 불변하다. 어차피 하위주소들만 변경되니까. 이를 companion object로 설정 했다.
companion object{
val array :Array<String> = arrayOf("서울특별시", "경상북도", "경상남도", "강원도", "전라북도", "경기도",
"인천광역시", "전라남도", "충청남도", "제주특별자치도", "세종특별자치시",
"충청북도", "광주광역시", "대구광역시", "대전광역시", "부산광역시", "울산광역시")
var addr1Entry = ArrayList<String>()
}
private val _addr2Entry= MutableLiveData<MutableList<String>>()
private val _addr3Entry= MutableLiveData<MutableList<String>>()
val addr2Entry: LiveData<MutableList<String>?> get() = _addr2Entry
val addr3Entry: LiveData<MutableList<String>?> get() = _addr3Entry
private lateinit var curAddr1:String //현재 선택된 주소
private lateinit var curAddr2:String
private lateinit var curAddr3:String
. . . . . .
//spinner event listener
fun onSpinnerItemSelectedAddr1 (parent: AdapterView<*>, view: View, position: Int, id: Long)
{ //주소1
_addrChange.value =1
curAddr1 = addr1Entry[position]
getAddr(curAddr1,"",2) //주소2 갱신
}
fun onSpinnerItemSelectedAddr2 (parent: AdapterView<*>, view: View, position: Int, id: Long)
{ //주소2
_addrChange.value =2
curAddr2 = addr2Entry.value!![position]
if(position>0) getAddr(curAddr1,curAddr2,3) //주소3 갱신
else {
var list = ArrayList<String>() //주소3 갱신X
list.add("전체")
_addr3Entry.value = list
}
}
fun onSpinnerItemSelectedAddr3 (parent: AdapterView<*>, view: View, position: Int, id: Long)
{ //주소3
_addrChange.value =3
curAddr3= addr3Entry.value!![position]
}
fun getAddr(addr1:String,addr2:String,type:Int)
{
compositeDisposable.add(
getAddrUseCase.execute(addr1,addr2)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ addrs ->
if (addrs.isEmpty()) {
println("비었음")
} else {
var list = addrs as ArrayList<String>
list.add(0,"전체") //전체 삽입
if(type==2) {_addr2Entry.value = list }
else {_addr3Entry.value = list}
}
}, {
println("통신실패")
}
)
)
}
MainActivity
addrChange.observe는 주소 변경시 하위 주소를 초기화 시켜준다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding.vm = viewModel
initViewModelCallback()
initSpinner()
}
private fun initViewModelCallback() { //callback
with(viewModel) {
...
//값 변경
addr2Entry.observe(this@MainActivity,Observer{
items2.clear()
items2.addAll(addr2Entry.value as ArrayList<String>)
addr2AdapterView.notifyDataSetChanged()
}
)
addr3Entry.observe(this@MainActivity,Observer{
items3.clear()
items3.addAll(addr3Entry.value as ArrayList<String>)
addr3AdapterView.notifyDataSetChanged()
}
)
//초기화
addrChange.observe(this@MainActivity,Observer{
when(addrChange.value){
1-> { //주소 1 변경
binding.addr2.setSelection(0)
}
2-> //주소 2 변경
binding.addr3.setSelection(0)
}
})
}
}
private fun initSpinner(){ //spinner 초기화
items1 = addr1Entry
items2 = ArrayList<String>()
items3 = ArrayList<String>()
addr1AdapterView = ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item,items1)
addr2AdapterView = ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item,items2)
addr3AdapterView = ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item,items3)
binding.addr1.adapter = addr1AdapterView
binding.addr2.adapter = addr2AdapterView
binding.addr3.adapter = addr3AdapterView
}
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- next.js import glsl
- 카드 짝 맞추기 javascript
- react 3d
- Vue.js
- 카카오 카드 짝 맞추기 javascript
- 카드 짝 맞추기 자바스크립트
- attempted import error: bvh_struct_definitions' is not exported from './gpu/bvhshaderglsl.js' (imported as 'bvhshaderglsl').
- rollup react.js npm
- next.js glsl
- react 3d text
- react leva
- rollup ts react npm
- typescript gsls
- react fiber 3d
- rollup typescript react
- react 3d 에니메이션
- webpack glsl
- leva
- vue3
- react three fiber leva
- 카카오 카드 짝 맞추기 자바스크립트
- rollup typescript
- vue
- ts glsl
- react three fiber
- 카카오 2021 카드 짝 맞추기
- eslint
- react 3d animation
- react glsl
- three.js leva
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함