마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

커스텀뷰에서 외부 버튼 클릭 이벤트를 알고 싶습니다!

0 추천
안녕하세요, MVVM 패턴에 Koin주입을 이용하여 앱 개발중입니다.

커스텀뷰를 이용하여 답지 버튼을 만들고 있습니다.

커스텀뷰(답번호)를 클릭하여 활성화하고 rightBtn이나 wrongBtn을 선택하면 해당 커스텀뷰(답번호)의 UI가 변경되어야 합니다.

시도 1. ViewModel에 LiveData 값의 변경을 관찰하여 상태를 변경할까 싶었는데 Observe시 필요한 LifeCycleOwner를 지정해줄 수 없었습니다.

시도 2. 리스너를 이용해서 rightBtn의 클릭 이벤트를 커스텀뷰에서 받아오려 했으나 하나의 프래그먼트에 50개가 넘는 버튼이 있는데 하나하나 연결해주는 것이 맞는지... 의문이 들었습니다.

 

어떻게 해결하면 좋을지 조언 부탁드립니다, 감사합니다!
하루도쉬운날이없어 (130 포인트) 님이 5월 10일 질문

1개의 답변

+1 추천

 만드신 커스텀 뷰에 리스너를 다세요. 아래와 같은 형태로 리스너를 외부에 노출시키세요.

class MyCustomView(...) {
     interface Listener {
           fun onItemClicked()
     }

  
    var listener: Listener? = null

    
     ....

     binding.aView.setOnclickListener {
            listener?.onItemClicked()
     }
}


이제 버튼 클릭 이벤트 리스너를 다는 것과 같은 패턴으로 처리하시면 됩니다. ViewModel에서 해당 이벤트 처리를 하게 되므로 LifecycleOwner는 필요가 없구요, ViewModelScope.launch 안에서 해당 이벤트를 처리하시면 됩니다.

 

// Activity or Fragment
private val viewModel by viewModels()  // Koin을 이용해서 처리할 것.


myCustomView.listener = object: MyCustomeView.Listener {
      override fun onItemClicked() {
           viewModel.onAnswerClicked()
       }
}


leftBtn.setOnClickListener {
     viewModel.onGoToPrevious()
}

rightBtn.setOnClickListener {
      viewModel.onGoToNext()
}


class MyViewModel: ViewModel() {

     fun onAnswerClicked() {
          // 선택한 답을 메모리나 스토리지에 저장/ LiveData에 설정. 
     }

   fun onGoToPrevious() {
       // 위에서 선택되었던 답을 검증하고 정답은 LiveData를 통해 뷰에 전달. 이전 문제로 이동.
   }

   fun onGoToNext() {
        // 위에서 선택되었던 답을 검증하고 정답은 LiveData를 통해 뷰에 전달. 다음 문제로 이동.
   }
}

Listener의 onItemClick 함수의 파라미터로 선택한 답을 넘기시면 원하는 답에 대한 처리가 가능하겠죠?
올려주신 코드가 없는 관계로 뼈대에 해당하는 코드만 작성했습니다.

2번 문제는 님이 뷰구조를 어떻게 가져가시느냐에  따라 처리방법이 달라지는데, 이것과 관련한 코드를 알 수가 없으므로 스킵하겠습니다.

spark (227,930 포인트) 님이 5월 10일 답변
spark님이 5월 10일 수정
저는 결국 프래그먼트에 onClickListener를 상속받고 dataBinding을 이용하여 리스너를 받아와 작업 후 ViewModel로 값을 넘겼는데, 알려주신 방법대로 하면 ViewModel 내부에서 처리할 수 있어 View단이 깔끔하네요..! 참고하여 수정하고 있습니다. 답변 정말 감사드립니다!!
...