본문 바로가기
ⓢⓣⓤⓓⓨ/ⓐⓝⓓⓡⓞⓘⓓⓢⓣⓤⓓⓘⓞ

[Android] databinding과 bindingAdapter

by heaven00 2022. 5. 25.
728x90

 

데이터바인딩이란?

=> 데이터와 뷰를 연결하는 작업을 레이아웃에서 처리 할 수 있게 해주는 라이브러리

 

 

즉, 예전에 이런씩으로 findViewById로 썼던 양식을 

    findViewById<TextView>(R.id.sample_text).apply {
        text = viewModel.userName
    }

아래의 @{} 양식으로 바꿔쓸 수 있는 것을 의미한다

<TextView
        android:text="@{viewmodel.userName}" />

 

이에따라 Activity에서 많은 UI 프레임워크 호출을 삭제할 수 있어 파일이 더욱 단순화되고 유지관리 또한 쉬워진다. 따라서 앱 성능이 향상되며 메모리 누수 및 null pointer exception을 방지할 수 있다.

 

 

🧐 쓰는 법 🧐

1. gradle에 추가

android{
    buildFeatures {
        dataBinding = true
    }
}

 

2. 데이터 클래스 세팅

data class HomeData (
    val image: Int,
    val name : String,
    val age : String,
    val mbti : String
)

 

3. layout이 감싸고 연결데이터를 표시하는 data 가 있는 형태로 바꿔주기

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

    </data>
 </layout>

 

4. viewmodel 등에서 데이터에 들어갈 값 선언

class ProfileViewModel : ViewModel() {

    val User = HomeData(R.drawable.ic_launcher_background,"이혜빈", "@hea_ven_00", "토킹포테이토? 아니 말도 못하는 포테이토")

}

 

5. 다음과 같이 데이터 경로를 설정해주고, 원하는 곳에 @{} 형태로 삽입

	<data>
        <variable
            name="data"
            type="com.sopt.android_hyebin.presentation.profile.ProfileViewModel" />
    </data>
    
    //중간 코드 생략
    ...
     	<TextView
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:fontFamily="@font/notosanskr_bold"
                android:includeFontPadding="false"
                android:text="@{data.User.name}"
                android:textColor="@color/white"
                android:textSize="20sp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/im_img"
                tools:text="nameTest" />
                
   //중간 코드 생략
   ...

 

 

<최종 정리>

1. Databinding을 사용하면 findViewById()를 쓰지 않아도 xml에 만든 View들을 자동으로 만들어 준다.
2. Data가 바뀌면 알아서 바뀐 Data로 View를 변경하게 할수도 있다. (Observe 사용시)

3. RecyclerView에서 각각의 item을 세팅 해주는 작업도 xml에서 다 써주면 알아서 척척 값이 들어간다. 
4. 구글에서 권장함

+) 바인딩 표현식은 단방향 또는 양방향으로 구성될 수 있으며, UI 의 버튼 클릭과 같은 이벤트의 응답으로 호출될 함수를 바인딩에 사용될 수 있다.

 

그럼 쟤가 bindingAdapter

결합 어댑터는 적절한 프레임워크를 호출하여 값을 설정하는 작업을 담당합니다. 한 가지 예로 setText() 메서드를 호출하는 것과 같이 속성 값을 설정하는 작업을 들 수 있습니다. 또 다른 예로는 setOnClickListener() 메서드를 호출하는 것과 같이 이벤트 리스너를 설정하는 작업이 있습니다.
데이터 결합 라이브러리를 사용하면 값을 설정하기 위해 호출되는 메서드를 지정하고 고유한 결합 로직을 제공하며 어댑터를 사용함으로써 반환된 객체의 유형을 지정할 수 있습니다.

 

내가 원하는 기능의 메서드가 없다면 어떻게 해야 할까? 액티비티에서 내가 원하는 메서드를 만들어 사용하듯이 레이아웃에서도 내가 원하는 메서드를 만들어 사용할 수는 없을까?

=> Binding Adapter를 사용하면 된다.

 

얘의 활용법 ?

  • object: Binding Adapter는 메모리상에 올려서 사용해야 하기 때문에 Object로 생성
  • @JvmStatic: 전역 변수의 Getter Setter를 정적 함수로 설정하는 어노테이션
  • @BindingAdapter: 괄호 안에 원하는 메서드 이름을 지어주면 된다. 
  • setImage: 이 메서드 이름도 원하는 걸로 정해주면 된다. 
object BindingAdapter {

//이미지 CROP
	@JvmStatic
    @BindingAdapter("imageBind")
    fun setImage(imageView: ImageView, imageUrl: Int) {
        Glide.with(imageView.context)
            .load(imageUrl)
            .circleCrop()
            .into(imageView)

    }
    
    
//TWIT인지 아닌지
    @JvmStatic
    @BindingAdapter("twitCheck")
    fun twitCheck(textView: TextView, twit: Boolean) {
        if(!twit){
            textView.visibility = View.GONE
        }else{
            textView.visibility = View.VISIBLE
        }
    }
}

쟤를 밑에 처럼 활용 가능!

        <ImageView
            android:id="@+id/iv_home_img"
            imageBind="@{twit.image}"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_marginStart="10dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/tv_home_name"
            tools:src="@drawable/property_1_android_read_profile_main" />
            
            
            
            <TextView
            android:id="@+id/tv_home_retwit_main"
            android:layout_width="wrap_content"
            android:layout_height="22dp"
            android:layout_marginTop="8dp"
            android:fontFamily="@font/roboto_medium"
            android:text="내가 리트윗한 트윗"
            android:textColor="@color/twitter_gray50"
            android:textSize="14sp"
            twitCheck="@{twit.isRetwit}"
            app:layout_constraintStart_toStartOf="@+id/tv_home_name"
            app:layout_constraintTop_toTopOf="parent" />

 

728x90

댓글