Grusie 안드로이드 개발 기술 블로그

[Android] Data binding 기본 사용법 및 BindingAdapter 본문

안드로이드 개발/라이브러리

[Android] Data binding 기본 사용법 및 BindingAdapter

grusie 2024. 4. 26. 17:42
728x90
반응형
SMALL

기존에 미라클알람 프로젝트를 진행하며 데이터바인딩에 대해 찍먹 정도는 해 본 적이 있다. 그 때는 잘 모르는 상태로 진행하여 코드도 난잡하고 사용하기 힘들었었고, 회사 프로젝트에 사용하려고 해 보았으나, data binding이 패키지명에 대문자가 있으면 에러가 나는 것 같았다. 하필 회사 프로젝트의 패키지명이 대문자로 되어있어 적용을 포기했었던 것 같다. 그 이후로 뷰바인딩만 사용하였고, 컴포즈 공부를 하면서, Data binding을 서서히 잊어갔다... xml의 사용을 줄이기위해 컴포즈로 공부하고 있었는데, 데이터바인딩은 오히려 XML에서 로직까지 사용하여 분리가 불가능 하게 될 것이라는 생각 때문이였다.

그러나 이번에 메모리즈 프로젝트를 진행하는데, 기존에 계셨던 분이 데이터바인딩으로 코드를 구현 해두었기에, 한 번 기술스택에 본인을 맞춰봐야겠다고 생각이 들었다.

 

 

데이터바인딩 기본 사용법

의존성 추가

모듈수준의 build.gradle에 dataBinding 사용 설정을 해준다.

android {
	. . .
    
    dataBinding {
    	enabled = true
    }
}

 

XML

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

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

    
    ...
</layout>

XML의 영역을 <layout> 태그로 감싼다.

<layout>태그 안에 필요한 데이터를 넣을 <data> 태그를 삽입하고, 원하는 변수의 이름과 타입을 지정하는 <variable>을 사용할 수 있다.

 

Class타입의 변수

<variable
    name="viewModel"
    type="com.example.memories.ui.main.calendar.CalendarViewModel" />
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="@{() -> viewModel.getCalendarAccountInfo()}"/>

이런식으로 하위 함수를 호출하는 형태로도 사용이 가능하다.

 

import 및 삼항연산자

<import type = "android.view.View"/>
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="@{text != null ? View.VISIBLE : View.GONE}"/>

추가로 필요한 import문이 있다면 import태그로 추가가 가능하고, 삼항 연산자도 사용이 가능하다.

 

코드

private val binding by lazy {ActivityMainBinding.inflate(layoutInflater)}

원하는 곳에서 뷰바인딩과 마찬가지의 형태로 binding 선언을 해주고, 데이터를 입력 할 때에는, binding.text 이런 변수 형태로 넣어주면 된다.

 

여기까지 간단한 데이터 바인딩에 대해 알아 보았고, 로직이 들어가는 데이터 바인딩을 처리하는 방법을 소개하겠다.

BindingAdapter를 활용하는 방법이다.

 

BindingAdapter 사용법

object BindingAdapter {

    @JvmStatic
    @BindingAdapter("app:hexToColor")
    fun setColor(view: View, hex: String){
        try {
            view.setBackgroundColor(Color.parseColor(hex))
        } catch (e:Exception) {
            view.setBackgroundColor(Color.TRANSPARENT)
        }
    }
}

우선 따로 생성자를 통해 생성할 필요 없도록 object에 만들어서 메모리에 올려두자.

@BindingAdapter 어노테이션을 통해, 원하는 속성 명을 지정해주고, 함수 내부에서 로직을 작성하면 된다.

view는 기본으로 가져가고, String타입인 색상 핵사코드를 가지고, Color로 변환시켜 배경 이미지를 바꾸는 방법이다.

 

파라미터를 여러개 사용할 경우

@JvmStatic
@BindingAdapter("app:version", "app:isVisible", requireAll = false)
fun setVersion(view: TextView, version: String? = "", isVisible:Boolean?= false){
    view.run {
        visibility = if(isVisible == true) View.VISIBLE else View.GONE
        text = "version : $version"
    }
}

여러 데이터를 가지고 데이터 처리를 하려면, BindingAdapter에 파라미터를 더 추가하고, 그에 맞는 로직을 작성하면 된다.

requireAll은 속성들이 반드시 전부 필요한지에 대해 설정하는 변수이다.

 

XML

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="393dp"
        android:background="@color/green_6BB53D"
        app:hexToColor="@{backgroundColor}">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="40sp"
            app:layout_constraintTop_toTopOf="parent"
            android:visibility="gone"
            app:version="@{version}"
            app:isVisible="@{isVisible}" />

이렇게 생성한 속성을 XML에서 사용하려면 이렇게 사용하면 된다.

생생한 차이를 위해, 기존 백그라운드를 녹색으로 해두고, TextView의 visibility를 gone으로 해두었다.

 

코드

class EditRecordActivity : AppCompatActivity() {
    val binding: ActivityEditRecordBinding by lazy {
        ActivityEditRecordBinding.inflate(layoutInflater)
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        binding.run {
            cardViewBackground = "#ff0000"
            version= "1.0.0"
            isVisible = true
        }
    }
}

이렇게 사용하면 원하는 결과가 나올 것이다.

 

결과

BindingAdapter를 활용한 결과물

 

참고

https://salmonpack.tistory.com/44

 

[Android] DataBinding 활용하기(1) - @BindingAdapter 매개변수 두개 이상 활용

findViewById... findViewById... find..View...by...... 😵‍💫😵‍💫 findViewById에 지치셨나요?? 🧐 언제까지 ViewId를 찾아다니실 건가요? 이제는 findViewById 없이 View Id 값을 바로 호출 할 수 있습니다. DataBindi

salmonpack.tistory.com

https://todaycode.tistory.com/53

 

Binding Adapter(바인딩 어댑터)를 배워보자!

1. Binding Adapter 1-1. Binding Adapter란? 2. 사용법 2-1. Adapter 2-2. Layout 2-3. Activity 3. Binding Adapter의 목적 4. 예제 1. Binding Adapter 1-1. Binding Adapter란? 뷰의 속성을 설정하는 메서드는 여러 가지가 있다. 당장

todaycode.tistory.com

 

https://heegs.tistory.com/59

 

[Android] 데이터 바인딩 어댑터 (Data Binding Adapter) 사용 방법

필자가 예전에 DataBinding 관련한 공부를 진행하면서 기본적인 사용 방법에 대해 간단히 작성해 둔 게시글이 있다. 이번에 클린 아키텍처 관련 예제를 작성하다 데이터 바인딩을 사용한 조금 더

heegs.tistory.com

https://markim94.tistory.com/163

 

Binding Adapter(결합 어댑터) 예제를 통해 이해하기

(본 포스팅의 예제는 뷰모델, 데이터바인딩, 라이브데이터의 기본 개념을 숙지하여야 이해가 용이합니다.) BindingAdapter는 Jetpack 라이브러리 기본 구성 요소인 "데이터 결합 라이브러리"의 내용 중

markim94.tistory.com

 

후기

솔직히 데이터바인딩의 필요성을 크게 느끼진 못하겠다. 코드의 가독성을 위함..? 아니면 뷰의 상태를 일관되게 유지? 흠.. 물론 LiveData로 옵저빙하여 변수를 하나씩 사용한다면 큰 의미가 있을 거 같기도 한데, StateFlowsealed classUiState를 만들어 관리한다면, 데이터바인딩으로 하는 것 보다 코드에서 하는 게 더 가독성이 좋을 것이라고 생각한다. 그래서 요즘은 viewBinding만 활용한다는 것 같으나, 이런 기술들도 사용 할 줄은 알아야 한다고 생각한다.

반응형
LIST