Android/Jetpack Compose

[Android] Epoxy를 사용하여 RecyclerView를 쉽게 사용해보자 -2. DataBinding

Heeg's 2022. 9. 5. 21:50
728x90

본 게시글은 이전 글에 이어서 작성된 부분입니다.

2022.09.01 - [Android/Utility] - [Android] Epoxy를 사용하여 RecyclerView를 쉽게 사용해보자 -1. 기본

 

이전 게시글에 이어서,

Epoxy에 DataBinding을 적용하여 사용하는 방법에 대하여 알아보도록 하겠다.


우선,

Epoxy에 Databinding을 사용하기 위해서는 Module 범위의 Gradle에 dependency를 추가해주어야 한다.

 

implementation "com.airbnb.android:epoxy-databinding:$epoxy_version"

 

물론, android 블록에 dataBinding에 대한 사용 설정도 해주어야 한다.

 

dataBinding {
    enabled = true
}

 

여기까지 추가해 주었으면,

기존에 만들었던 Controller와 DataModel은 사용하지 않을 것이므로 Class 자체를 전부 주석 처리 혹은 제거 해주고 진행하도록 하겠다.

 

DataModel은 epoxyRecyclerView와 xml로 선언한 layout을 바인딩해주고,

Controller는 epoxyRecyclerView에 DataModel을 사용하여 값을 세팅하여 recyclerView에 UI를 추가해주는 역할을 수행했다.

그리고, Databinding을 이용하게 되면 위의 작업들의 일부를 생략하고, activity에서 호출할 때 생략하지 못하는 작업들을 선언하여 사용할 수 있다.

 

Databinding을 사용하기 위하여 추가적으로 생성해야 하는 것은 사용할 layout을 binding 하는 부분이 필요하다.

 

@EpoxyDataBindingPattern(rClass = R::class, layoutPrefix = "epoxy")
object EpoxyDataBinding

 

@EpoxyDataBindingPattern 어노테이션을 선언해둔 Object를 이처럼 선언하기만 하면 된다.

rClass 부분은 Epoxy 모듈이 사용할 클래스를 선언해주는 부분이다. R::class로 선언하게 되면 해당 프로젝트에서 선언된 R로 시작하는 클래스를 모두 사용할 수 있게 된다.

즉, R.layout.~ 형태의 파일을 모두 조회하여 사용할 수 있다는 의미가 된다.

 

그리고, layoutPrefix 부분은 xml파일에서 epoxy Databinding에 사용할 layout을 지정해주는 부분이다.

Prefix가 epoxy인, epoxy_~ 형태로 되어있는 xml파일을 사용할 수 있다는 것이고, 이러한 파일들을 model 클래스로 생성하여 사용할 수 있게 된다.

이때, 생성되는 Model 클래스는 prefix 부분을 제외, 파스칼 표기법을 사용하며 접미에 BindingModel_ 을 붙인 형태가 된다.

즉, epoxy_data_view.xml 파일이 있다면, DataViewBindingModel_ 형태의 Model클래스를 자동으로 생성해 준다.

 

이렇게 선언해주었으면, 기존 MainActivity에서 epoxyRecyclerView를 사용했던 부분을 변경해주도록 하자.

우선 controller를 사용하지 않기 때문에 기존에 선언해 두었던 controller 변수 또한 제거해주도록 하고, 별도로 뿌려줄 데이터를 임의로 생성해주도록 하였다.

 

private val dummyData = ArrayList<Title>()
private fun init() {
    dummyData.add(Title("11"))
    dummyData.add(Title("22"))
    dummyData.add(Title("33"))
    dummyData.add(Title("44"))
    dummyData.add(Title("55"))
}

 

실제로 사용할 때는 data class를 만들고, 해당 데이터 포맷에 맞춰서 사용하는 경우가 많기 때문에 String 타입 하나만 존재하는 data class인 Title을 만들어서 진행하였다.

String 타입의 ArrayList를 만들고, 이전 글과 동일하게 사용해도 무관하다.

 

다음으로,

recyclerView에 사용할 xml 파일에 databinding을 사용할 수 있게 처리해주도록 하자.

 

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

    <data>

        <variable
            name="title"
            type="String" />
    </data>

    <TextView
        android:id="@+id/epoxyTitle"
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
        android:gravity="center"
        android:text="@{title}" />
</layout>

 

기존에 사용했던 부분에서, dataBinding을 통해 값을 설정하기 위하여 <layout> 태그로 최상단을 감싸주고, <data> 태그를 통해 사용할 값을 지정해주도록 하였다.

이에 대한 부분은 Epoxy 사용과는 무관하므로 넘어가도록 하겠다.

 

 

마지막으로,

epoxyReclerView에 대한 설정만 바꿔주면 된다.

 

private fun beforeSetItem() {
    val linearlayoutManager = LinearLayoutManager(this)

    binding.epoxyRecyclerView.apply {
        layoutManager = linearlayoutManager
        setHasFixedSize(true)
        adapter = controller.adapter
    }
    controller.requestModelBuild()
}

 

private fun newSetItem() {
    val linearlayoutManager = LinearLayoutManager(this)

    binding.epoxyRecyclerView.apply {
        layoutManager = linearlayoutManager
        setHasFixedSize(true)

        withModels {
            dummyData.forEach {
                dataView {
                    id("dataBindingItem")
                    title("V : $it")
                }
            }
        }
    }
}

 

비교를 위해서 기존에 사용했던 코드도 추가를 해보았다.

달라진 부분은, controller를 사용하지 않기 때문에 adpater 세팅 부분, update 하는 부분이 제거되었다는 점, withModels 블록이 생겼다는 점이다.

withModels 블록을 확인해보면, 기존에 Controller의 buildModels에 선언해둔 것과 거의 흡사한 모습을 볼 수 있다.

즉, 해당 블록 내에서 필요한 데이터를 넣은 객체를 생성하여 recyclerView에 추가해준다는 것이다.

 

위에서 임시로 만든 dummyData를 전부 추가해주기 위해 forEach를 사용하였고, 중요한 것은 그 내부에 선언된 dataView 블록이다. 기존에 사용하던 방식과 다른 형태를 보이고 있으며, 해당 아이템을 add 해주는 부분이 존재하지 않는다.

하지만, 

 

DataViewBindingModel_()
    .id("addId")
    .title("normal : $it")
    .addTo(this)

dataView {
    id("addId")
    title("V : $it")
}

 

 

두 개의 타입으로 선언이 가능할 뿐, 기능은 다르지 않다.

기존에 사용하던

ABindingModel_().setting(...).addTo()

형태 대신

A { setting(...) } 

형태로 더욱 간결하게 사용이 가능해지는 것이다.

 

여기서 title로 사용한 부분은 epoxy_data_view.xml에서 선언한 title을 의미하는 것이다.

기존에 DataModel Class에서 @EpoxyAttribute 어노테이션을 통해 명시한 부분을 이와 같이 변경하여 사용하는 것이다.

 

이렇게 작성한 후에 빌드를 해보면 다음과 같은 결과가 나오게 된다.

 

 

 

출력하는 data type이 변경되어 다른 값이 출력되었지만, 결과적으로 동일한 형태의 recycerview를 그리게 된다.


기본적인 방법으로 사용했을 때는 Epoxy에 대한 이점을 확실하게 느낄 수 없었던 반면, DataBinding을 사용하는 경우 코드의 양이 눈에 띄게 줄어들고, 보다 쉽게 사용할 수 있게 변경되기 때문에 Epoxy에 대한 이점을 확실하게 느낄 수 있는 것 같다.

 

Databinding을 사용하여 Controller와 DataModel Class에서 선언한 부분을 생략할 수 있기 때문에 이 두 개의 클래스는 제거할 수 있으며, @EpoxyDataBindingPattern 어노테이션과 withModels 블록을 통해 아주 간단하게 recyclerView에 대한 설정을 할 수 있는 것이다.

 

좀 더 Epoxy에 익숙해지고 다양한 활용 방법을 경험한다면, 확실히 일반적인 RecyclerView를 사용하지 않고 Epoxy를 사용하는 것이 여러모로 효율적일 것 같다는 생각이다.

 

 

GitHub를 확인해보면, 이처럼 RecyclerView가 사용되는 다양한 부분에 대해서 대응을 해주고 있으며, 계속해서 업데이트가 이루어지고 있어서 당장 적용해서 사용하는 것에도 문제가 없을 것으로 보인다.

 

필자가 Epoxy를 사용해서 이것저것 테스트를 해보았을 때, 많이 사용하는 layout에 대해서도 쉽게 적용할 수 있다는 것을 확인했지만, 몇 가지 옵션들을 사용하는 것에는 시행착오를 겪은 것들이 있었다.

본 게시글에 관련된 것들도 작성할까 생각하였지만, 확실히 구분지어 글을 작성하는 것이 추후에 확인하기도 편할 것이라고 생각하여 글을 나누어 작성하고자 한다.

 

다음 게시글에서는 GirdLayout, Carousel에 대하여 간단하게 적용하는 방법에 대하여 작성해볼 예정이다.

 

해당 게시글에 사용된 예제 코드는 Github에 올려두었다.

https://github.com/HeeGyeong/EpoxySample

 

GitHub - HeeGyeong/EpoxySample

Contribute to HeeGyeong/EpoxySample development by creating an account on GitHub.

github.com

 

728x90