Android

[Kotlin] DataBinding 사용하기

Wootaeng 2021. 12. 23. 17:40
728x90
  • 데이터 바인딩

데이터 바인딩의 주목적은 UI 레이아웃의 뷰를 앱 코드에 저장된 데이터와 연결하는 간단한 방법을 제공하는 것.

데이터 바인딩은 또한, 버튼과 같은 UI 컨트롤을 UI컨트롤러 또는 ViewModel 인스턴스와 같은 다른 객체의 이벤트나 리스너 함수에 연결 시키는 편리한 방법도 존재ㅐ.

특히 LiveData 컴포넌트와 같이 사용 될 때 이점이 배가 된다.

구글 공식문서(https://developer.android.com/topic/libraries/data-binding?hl=en) 에는 아래와 같이 설명 되어있다.

레이아웃에 있는 UI 구성요소를 선언적으로 사용하는 방식이라는 건데..

아직도 잘 모르겠다. 일단 시도해보자

  • Gradle 추가
android{

    buildFeatures {
        dataBinding = true
    }

}
  • activity_main.xml 수정
<androidx.constraintlayout.widget.ConstraintLayout
        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"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/name_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.415" />

        <TextView
            android:id="@+id/email_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.595" />
    </androidx.constraintlayout.widget.ConstraintLayout>

위의 코드가 기존 xml 코드이다.

데이터바인딩을 사용하기 위해서는 레이아웃에 선언을 해주어야한다.

<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">

    <androidx.constraintlayout.widget.ConstraintLayout

        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/name_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.415" />

        <TextView
            android:id="@+id/email_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.595" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

을 사용해서 xml 을 전체 감싼다.

이렇게 적용하여도 MainActivity 에서

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

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

.
.
.
}

사용이 가능해진다.

그런데 이렇게 사용하면 ViewBinding 과 다를 게 없지 않는가?

데이터 바인딩의 단방향 , 양방향 표현을 사용하려면 xml 에 추가 작업이 필요하다

그 작업을 하기 위해서는 레이아웃에서 사용할 객체에 대한 Data 파일을 만들어야한다

data class Student (
    var id:Int,
    var name:String,
    var email:String
)

간단하게 학생 클래스를 만들었다

만들어주고 xml에 해당 객체를 사용하겠다고 선언을 한다.

<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="student"
            type="com.anushka.bindingdemo3.Student" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout

를 이용하고 그 안에 사용할 변수 이름과 참조 할 클래스를 연결한다.

바인딩 표현식을 이용하여 특정 뷰가 바인딩 객체와 어떻게 상호작용하는지를 정의한다.

<androidx.constraintlayout.widget.ConstraintLayout

        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/name_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="30sp"
            android:text="@{student.name}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.415" />

        <TextView
            android:id="@+id/email_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="30sp"
            android:text="@{student.email}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.595" />
    </androidx.constraintlayout.widget.ConstraintLayout>

바인딩 표현식은 @ 로 시작하며 { } 안에 표현식을 넣는다.

위에 보면 name과 email 변수를 포함하는 student 인스턴스를 위에 처럼 바인딩 레이아웃 파일에 선언이 가능하다.

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main)
        binding.student = getStudent()

// 레이아웃 에 <data > 선언으로 별도의 선언 없이 객체를 레이아웃에 직접 전달하여 데이터 바인딩과 함께 사용가능
//        val student =getStudent()
//        binding.nameText.text = student.name
//        binding.emailText.text = student.email
    }

    private fun getStudent():Student{
        return Student(1,"Alex","alex@gmail.com")
    }
}

원래라면 binding.nameText.text = student.name 을 이용해서 넣었을텐데

이미 레이아웃에 선언을 해두었기에 그 과정이 생략이 되게된다.

실행해보면 값이 잘 들어가는 것이 확인된다.

  • 요약

데이터 바인딩은 UI 레이아웃의 뷰와 앱의 다른 객체의 데이터나 함수 간의 연결을 생성하는 시스템을 제공한다. 그리고 최초에 필요한 구성을 해주면, 레이아웃의 뷰에 바인딩 표현식을 사용할 수 있다. 바인딩 표현식은 단방향 또는 양방향으로 구성될 수 있으며, UI 의 버튼 클릭과 같은 이벤트의 응답으로 호출될 함수를 바인딩에 사용될 수 있다.

  • 느낀 점

액티비티 부분에 별도의 코드를 작성하지 않아도 되는 이점이 제일 큰 장점인 듯 하다.

뷰바인딩 보다도 더 단축 되는 느낌.

하지만 레이아웃을 건드려야 하고 @ { } 이 바인딩 표현식이 너무 낯설다.

저번에 했던 뷰바인딩과 비교하면 별도의 클래스도 만들고 하여 무거워진다는 단점이 있는 듯 하다.

ViewModel 또는 LiveData 와 같이 사용을 하면 시너지가 있어서 규모가 큰 회사나 앱에서는 데이터 바인딩을 주로 사용하는 느낌이다.

뷰바인딩과 데이터 바인딩의 실제 앱에서는 어떤식으로 체감이 되는지.

앞으로 계속 알아나가보자.

 

728x90
반응형