물에 살고싶은 개발자

[Databinding] 3. RecyclerView에서 데이터바인딩 사용법 본문

카테고리 없음

[Databinding] 3. RecyclerView에서 데이터바인딩 사용법

돼지사랑 2022. 7. 10. 13:43

이전 작성 글

1. 데이터바인딩 기본 사용법

 

[Databinding] 1. 데이터바인딩 기본 사용법

이번엔 데이터 바인딩 사용법에 대해 최대한 짧은 글을 써볼까 한다. 이 글을 작성하는데에 있어 이 블로그의 도움을 많이 받았고, 덕분에 이 글을 쓰게 됐음을 미리 밝힌다. 이 글은 사용법을

ppost.tistory.com

2. 데이터바인딩 BindingAdapter 사용법

 

[Databinding] 2. 데이터바인딩 BindingAdapter 사용법

저번 글에 이어 바인딩어댑터의 사용법을 적어볼까 한다. 저번 글에서 사용법을 설명한 데이터 바인딩에 대한 지식이 있어야 이해하기 쉬울것이다. 일단 최대한 요약해서 결론부터 적어보자면,

ppost.tistory.com

 

 

이번 글은 다소 짧을 수 있다. 사실 저번 바인딩어댑터 사용법까지 이해했다면, 가볍게 응용하는걸로도 충분하기때문.

이번 글의 결과물은 일반 RecyclerView의 결과물과 같기때문에 코드만 보여주겠다. 프로젝트는 이전 글을 작성할때 사용했던 것들과 동일하다.

 

1. MainActivty.kt 

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        binding.apply {
            // 뷰모델 객체를 바인딩시켜준다. 상황에 따라선,
            // 뷰모델 프로바이더 등을 이용해 바인딩 시켜줄 수 도 있다.
            // 여기선 예제이므로, 유저리스트만 갖고있는 클래스로 예시를 들겠다.
            vm = ViewModel()

            // RecyclerView 세팅
            val layoutManager = LinearLayoutManager(this@MainActivity) //레이아웃 매니저 설정
            layoutManager.orientation = LinearLayoutManager.VERTICAL
            rv.layoutManager = layoutManager
        }
    }

메인액티비티에 onCreate() 함수 내부이다. 액티비티에서 할 것은 저것이 끝 ! 자세한 설명을 할것도 없다. 그냥 우리가 잘 알고있는 RecyclerView 세팅 코드에서 어댑터 세팅만 빠졌을뿐이기때문!

 

2. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

        <variable
            name="vm"
            type="com.cary.tempproject.ViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:overScrollMode="never"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:setAdapter="@{vm.userList}"
            />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View파일인 xml 역시 별것없다. 다만, 이번엔 뷰모델이 추가되었는데, 이건 MVVM이라는 전제하에 간단한 예시코드라서 뷰모델은 그저 userList를 갖고있을뿐이다. MVVM과 데이터바인딩에 대한것은 다음 글에서 설명할 예정이니 일단은 그냥 뷰모델안에 userList가 있고, 그걸 rv에 세팅해준다 정도로만 이해하고 넘어가자.

조금만 더 설명하자면, 다음글을 위한 빌드업의 일환으로 vm을 썻을뿐, 그냥 메인액티비티에서 만든 리스트를 넣어줘도 된다. 세팅되는 데이터가 리스트인 이유는 추측가능한사람도 있겠지만, 다음 바인딩어댑터에서 설명하겠다.

 

3. CustomBindingAdapter.kt

object CustomBindingAdapter {
    @BindingAdapter("setAdapter")
    @JvmStatic
    fun setAdapter(recyclerView: RecyclerView, items: List<User>?) {
        if (recyclerView.adapter == null) {
            val adapter = MainActivity.UserAdapter()
            recyclerView.adapter = adapter
        }

        val myAdapter = recyclerView.adapter as MainActivity.UserAdapter

        items?.let {
            myAdapter.userList = it
            myAdapter.notifyDataSetChanged()
        }
    }
}

바인딩어댑터를 이용해 어댑터 세팅코드를 이쪽으로 옮겨줫다. 그걸로 끝 ! 

데이터가 갱신될때마다 호출되어 유저리스트를 새로고침해주는것이다.

 

 

4. UserAdapter

class UserAdapter :
        RecyclerView.Adapter<UserAdapter.ViewHolder>() {
        var userList: List<User>? = listOf()

        override fun onCreateViewHolder(
            parent: ViewGroup,
            viewType: Int
        ): ViewHolder {
            val binding =
                ItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
            return ViewHolder(binding)
        }

        override fun onBindViewHolder(holder: ViewHolder, i: Int) {
            holder.bind(userList?.get(i))
        }

        // 생성된 뷰 홀더에 값 지정
        class ViewHolder(private val binding: ItemBinding) :
            RecyclerView.ViewHolder(binding.root) {
            fun bind(user: User?) {
                binding.user = user
            }
        }

        override fun getItemCount(): Int = userList?.size!!        
    }

어댑터코드 역시 매우 심플해진걸 확인 할 수 있다. 

주목할건 기존에 itemView에 데이터를 세팅을 담당하던 onBindViewHolder() 혹은 ViewHolder 클래스의 

코드가 확 줄어든걸 확인할 수 있다. 메인액티비티에서 그랫듯, 어댑터 역시 뷰홀더를 통해 xml파일에 데이터클래스인 User 객체를 바인딩시켜주면 된다.

 

5. item.xml 

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="user"
            type="com.cary.tempproject.User" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/nameTv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:text="@{user.name}"
            android:textSize="14sp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

굳이 볼 필요가 있을까? 싶을정도로 심플하다. 메인액티비티와 마찬가지로 데이터바인딩용(?)으로 교체해주고 데이터바인딩만 시켜주면 끝이다. 

 

 

 

이로써 사용법에 대한것은 끝이다. 물론, 이는 가장 심플한 사용법에 대한 예제이기때문에, 필요에 따라 응용을 더 하게 될 수도있다. 다음글에선 MVVM구조에서 응용하는법...을 적을까 하지만 그리 길지 않을지도 모르겠다 -_-;; 

 

끝!

Comments