지난 글에서 빼먹은 부분이 있다. 리사이클러뷰에서 이벤트 리스너를 연결하는 방법인데, 지금 상태에서 무지성으로 리스너를 연결한다면 아마 bind 함수에서 하게될 것이다. 이번 글에서는 Adapter 에 ViewModel 을 받아 사용하는 방법을 알아보자. 지난 글에 이어서 설명하겠다. 이번에는 지난 번보다 짧다.
1. 이벤트 함수 구현
class MainViewModel : ViewModel() {
// ...
fun showToastMessage(view: View, text: String) {
Toast.makeText(view.context, text, Toast.LENGTH_SHORT).show()
}
}
내가 실제로 코딩한 순서는 이것과 다르지만, 글에서는 컴파일 에러가 나지 않는 순서대로 진행할 예정이다. 함수 바디 부분은 간단해서 설명할 부분이 없고, 파라미터로 View 와 String 을 받는다는 것만 확인하고 넘어가겠다.
2. xml 파일에서 메소드 바인딩
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="item"
type="org.algosketch.datebindingtest.ExampleItem" />
<variable
name="viewModel"
type="org.algosketch.datebindingtest.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
tools:text="여기 적힌 내용이 토스트 메시지로 출력될 거야!"
android:text="@{item.content}"
android:onClick="@{(view)->viewModel.showToastMessage(view, item.content)}"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
새로운 변수 viewModel 을 추가했다. Button 의 onClick 부분에서 방금 구현한 함수를 바인딩 시켜준다. 위 코드처럼 View 자신을 인자로 넘길 수 있고, 다른 인자도 추가해서 넘길 수 있다. 다만 자동완성이 안 되기 때문에 IDE 가 큰 도움이 되지는 않는다.
3. Adapter 에 ViewModel 추가
class ExampleAdapter(private val viewModel: MainViewModel) : RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder>() {
// ...
override fun onBindViewHolder(holder: ExampleViewHolder, position: Int) {
holder.bind(viewModel, exampleList[position])
}
// ...
class ExampleViewHolder private constructor(val binding: ItemExampleBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(viewModel: MainViewModel, item: ExampleItem) {
binding.item = item
binding.viewModel = viewModel
binding.executePendingBindings()
}
// ...
}
}
Adapter 생성자에 ViewModel 을 추가하고 bind 메소드를 통해 바인딩 시켜준다.
class MainActivity : AppCompatActivity() {
val viewModel: MainViewModel by viewModels()
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
// ...
setupAdapter()
}
fun setupAdapter() {
binding.exampleRecyclerView.adapter = ExampleAdapter(viewModel)
}
}
Adapter 의 생성자가 변경되었으므로 MainActivity 또한 수정해준다. 다음 글에서는 진짜로 DiffUtil 사용 방법에 대해 작성하겠다.
'안드로이드' 카테고리의 다른 글
[안드로이드] 반응형을 고려한 xml 마크업 (ConstraintLayout) (0) | 2022.02.26 |
---|---|
[안드로이드] layout <include> 속성 정의 및 이벤트 구현하기 (0) | 2022.02.10 |
[안드로이드] 애플리케이션 아키텍처 (0) | 2022.01.23 |
[안드로이드] 리사이클러뷰 데이터 바인딩 (RecyclerView data binding) (1) | 2022.01.15 |
[안드로이드] ViewModel 에서 이벤트 처리하는 방법 (SingleLiveEvent) (0) | 2022.01.14 |