오늘도 더 나은 코드를 작성하였습니까?

DataBinding Component 사용하기 본문

Android Jetpack Architecture/DataBinding

DataBinding Component 사용하기

hik14 2020. 8. 7. 20:51

DataBinding Component란?

DataBindingComponent는 BindingAdapter에 대한 getter를 포함하는 인터페이스다.

 

DataBindingComponent를 구현하는 클래스는 반드시 하나이상의 메서드를 가져야 한다.

 

메서드의 이름은 접두어 get과 @BindingAdapter 메서드를 포함하는 클래스 또는 인터페이스의 이름의 합성어여야 한다.

 

예를 들어 @BindingAdapter 메서드를 가지고 있는 클래스의 이름이 ClickBinding이라면 DataBindingComponent구현체가 갖는 메서드의 이름은 getClickBinding()이 된다

 

BindingAdapter를 통해 사용자 정의 따른 로직과 setter를 수행할 수 있다 하지만 @BindingAdapter 메서드는 static을 붙여 선언한다. 그러므로 상태를 저장하거나 close(), clear(), dispose()와 같은 메서드 등을 호출하여 리소스를 정리하는데 어려움이 있다. 

 

DataBindingComponent는 이러한 문제점을 해결하는데 도와주며 동적으로 바인딩 어뎁터를 바인딩 클래스에 추가시킨다. 

 

 

바인딩 클래스를 초기화할 아래와 같이 마지막 매개 개변 수로 넣어줌으로써 설정 가능하다.

DataBindingUtil.setContentView(activity, layoutId, bindingComponent)
DataBindingUtil.inflate(..., bindingComponent)
DataBindingUtil.bind(view, bindingComponent)

솔직히 잘 이해가 안 된다.....

 

stackoverflow에서 가져온 내용인데.

 

This tells us this interface is used and generated for injecting a factory for instances implementing custom @BindingAdapter methods. Like this you can configure the data bindings for different situations or layouts or supply it with a more general state. If you have a look at the default DataBindingComponent class in Android Studio you find it located in build/generated/source/apt/dev

 

이는 이 인터페이스가 커스텀 @BindingAdapter 메서드를 구현하는 인스턴스의 팩토리를 삽입하는 데 사용되고 생성되었음을 알려줍니다. 이와 같이 다양한 상황이나 레이아웃에 대한 데이터 바인딩을 구성하 거나 보다 일반적인 상태를 제공할 수 있습니다. Android 스튜디오의 기본 DataBindingComponent 클래스를 살펴보면 build / generated / source / apt / dev에 있습니다.

 

 

잘 이해가 되지 않지만 일단 이해한 내용은 정리해보겠다.

 

1. 다음과 같이 3개의  인터페이스를  생성한다. 

 

ImageViewBindingInterface.java

public interface ImageViewBindingInterface {
    @BindingAdapter({"bind:imageUrl", "bind:error"})
    public  void loadImage(ImageView view, String url, Drawable error);
}

TextViewBindingInterface.java

public interface TextViewBindingInterface {
    @BindingAdapter({"bind:font"})
      void setFont(TextView textView, String fontName);
}

ViewBindingInterface.java

public interface ViewBindingInterface {
    @BindingAdapter("android:paddingLeft")
    public  void setPaddingLeft(View view, int padding);
    @BindingAdapter("android:onViewAttachedToWindow")
    public  void setListener(View view, ViewBindingAdapter.OnViewAttachedToWindow attached);
}

 

2. The DataBindingComponent.java 자동적으로 업데이트된다.

 

위의 3개의 인터페이스를 생성하면 다음과 같이 확인할 수 있다.

 

 

3. 각 3개의 인터페이스에 대해 기본적인 구현 클래스를 만들어보자

 

BaseImageViewBinding.class

public class BaseImageViewBinding implements ImageViewBindingInterface{

    @Override
    public void loadImage(ImageView view, String url, Drawable error) {
        Picasso.get().load(url).error(error).into(view);
    }
}

BaseTextViewBinding.class

public class BaseTextViewBinding implements TextViewBindingInterface {

    @Override
    public void setFont(TextView textView, String fontName) {
        textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));
    }
}

BaseViewBinding.class

public class BaseViewBinding implements ViewBindingInterface {
    @Override
    public void setPaddingLeft(View view, int padding) {
        view.setPadding(padding,
                view.getPaddingTop(),
                view.getPaddingRight(),
                view.getPaddingBottom());
    }

    @Override
    public void setListener(View view, ViewBindingAdapter.OnViewAttachedToWindow attached) {

    }



}

 

4. OwnDatabindingComponent을 만들자.

 

- 2번에서 자동 생성된 데이터 컴포넌트를 구현한다.

public class MyOwnDefaultDataBindingComponent implements androidx.databinding.DataBindingComponent {
    @Override
    public ViewBindingInterface getViewBindingInterface() {
        return new BaseViewBinding();
    }
    @Override
    public TextViewBindingInterface getTextViewBindingInterface() {
        return new BaseTextViewBinding();
    }
    @Override
    public ImageViewBindingInterface getImageViewBindingInterface() {
        return new BaseImageViewBinding();
    }
}

 

5. 앱에 바인딩 컴포넌트를 설정해 보자!

package com.professionalandroid.apps.databindingcomponent;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import android.graphics.drawable.Drawable;
import android.os.Bundle;

import com.professionalandroid.apps.databindingcomponent.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding mBinding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Drawable drawable = getDrawable(R.drawable.ic_launcher_background);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main, new MyOwnDefaultDataBindingComponent());
        mBinding.setErrImage(drawable);
        mBinding.setUrl("https://image.auction.co.kr/itemimage/19/4c/f2/194cf2bba6.jpg");
    }
}
<?xml version="1.0" encoding="utf-8"?>

<layout>

    <data>
        <variable
            name="errImage"
            type="android.graphics.drawable.Drawable" />

        <variable
            name="url"
            type="String" />
    </data>
    <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">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:error="@{errImage}"
            app:imageUrl="@{url}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

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

예시 코드는 잘되긴 하고 일단 내가 이해한 대로 정리를 해보자면

 

바인딩 컴포넌트가 사용자 정의 @BindingAdapter 메서드를 구현하는 인스턴스(ㅠBaseImage ViewBinding, BaseTextViewBinding, BaseViewBinding 등 )에 대한 팩토리를 주입하기 위해 사용된다

 

아래와 같이 각 @BindingAdapter를

DI와 함께 활용되어서 다양한 상황이나 레이아웃에 대한 데이터 바인딩을 구성하 거나 보다 일반적인 상태를 제공할 수 있습니다. 

 

public class MyOwnDefaultDataBindingComponent implements androidx.databinding.DataBindingComponent {
    @Override
    public ViewBindingInterface getViewBindingInterface() {
        return new BaseViewBinding();
    }
    @Override
    public TextViewBindingInterface getTextViewBindingInterface() {
        return new BaseTextViewBinding();
    }
    @Override
    public ImageViewBindingInterface getImageViewBindingInterface() {
        return new BaseImageViewBinding();
    }
}

 

Android Studio의 기본 DataBindingComponent 클래스를 살펴보면 build / generated / source / apt / dev에 있습니다.