안드로이드

[Android/Kotiln] DataBinding(데이터바인딩)3 - Observable(실시간 데이터)

mingmaeng 2020. 2. 6. 12:19

이번 포스팅에서는 데이터를 실시간으로 관찰할 수 있는 Obsevable 데이터에 대해서 알아보도록 하겠다.

이전 포스팅과 연관되는 부분은 아니지만 그래도 이전 포스팅들을 보고 오면 좋다.

 

1. DataBinding 1 - 기초

2. DataBinding 2 - BindingAdapter

 


실시간으로 데이터를 관찰해보자!

기존 안드로이드 개발을 할 때 화면에 보여주는 데이터에 변화가 생긴다면 어떻게 했는지를 생각해보자.

A 텍스트 뷰에 적혀 있는 글자를 버튼을 눌러 다른 글자로 바꿀 경우 우리는 다음과 같이 값을 바꿔주었다.

 

text_A.text = "내가 변경할 값"

 

이는 데이터가 변경될 때마다 우리가 직접 그 변경됨을 xml에 알려줘야 함을 의미한다. 그래서 우리는 값이 변경되면

뷰에서 알아서 변화를 감지해 변화된 값으로 변경시켜주기 위해서 Observable을 사용한다.

 

식별이 가능한 필드

Observable은 실시간으로 데이터를 관찰하기 위해 사용된다. 기본적으로 ObservableField를 이용하는데, 기본적으로 안드로이드에서 제공해주는 단일 필드가 있는 독립적인 식별 가능한 개체다.

Android Developer에 있는 예시를 보자. 사람의 성인 firstName과 이름인 lastName, 그리고 나이인 age를 변수로 가지고 있는 User객체가 있다고 할 때 ObservalbeField를 이용해서 실시간으로 관찰 가능한 데이터로 만들게 되면

다음과 같이 작성할 수 있다.

 

class User {
        val firstName = ObservableField<String>()
        val lastName = ObservableField<String>()
        val age = ObservableInt()
    }

ObservalbeField는 박싱 및 언박싱을 방지하기 때문에 val로 설정해주어야 한다. 필드 값을 저장(set)하거나

불러오려면(get) 우리가 알고 있는 방식대로 저장하고 불러오면 된다.

 

 user.firstName = "Google"
 val age = user.age

 

실시간 관찰이 가능한 개체

Observable 인터페이스를 구현하는 클래스를 사용할 대 식별 가능한 개체의 속성 변경에 관해 알림을 받으려는 리스너를 등록할 수 있다. 간단하게 말하자면 getter와 setter를 등록할 수 있다는 것이다.

BaseObservable이라는 클래스를 이용하여 간단하게 구현할 수 있다. 실습한 내용을 보면서 사용법을 알아보자.

 

Observable을 사용해서 실습을 해보자!

간단한 실습예제를 해보자.

텍스트 뷰의 내용을 3초 후에 다른 내용으로 변경시키는 간단한 예제다.

먼저 변화를 감지하기 위해 Observable을 이용해  Data Class를 만들어 준다.

 

ObservableData.kt

class ObservableData : BaseObservable(){

    @get:Bindable
    var site : String = ""
    set(value) {
        field = value
        notifyPropertyChanged(BR.site)
    }
}

 

ObservableData라는 이름을 가진 데이터 클래스를 하나 만들어 주었다. 여기에는 사이트의 이름이 들어갈 site변수를 하나 만들어 주었고, 이 변수를 실시간으로 관찰이 가능한 데이터로 만들어 주었다.

위에서 Observable 인터페스를 구현하는 클래스는 getter와 setter를 등록할 수 있다고 했다.

코틀린은 자바와는 다른 방식으로 구현할 수 있는데, @get:Bindable을 이용해 getter에 할당하고 setternotifyPropertyChanged() 메서드를 호출함으로 작업을 완료한다.

처음에 BR이라는 부분이 정의되지 않아서 BR.site가 빨간줄이 뜰 수도 있는데 Build를 하거나 실행을 하면 정상적으로 돌아오기 때문에 너무 신경쓰지 않아도 된다.

 

이제 힘든건 다 끝났다. 나머지는 우리가 알고 데이터바인딩 방식대로 TextView에 데이터를 바인딩 시켜주고, 액티비티에서 Handler()를 통해 3초 후 TextView를 변경해주기만 하면 끝이다.

 

activity_main.xml

<data>
      ...
        <variable
            name="site"
            type="org.techtown.databinding.ObservableData" />
</data>

...

<TextView
            android:id="@+id/siteName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{site.site}"
            tools:text="siteName"/>

 

MainActivity.kt

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.activity = this@MainActivity
        ...
        setObserv()
    }
    ...
    
    fun setObserv(){
        var item : ObservableData = ObservableData()
        item.site = "Naver"
        binding.site = item

        Handler().postDelayed(Runnable {
            run {
                item.site = "Google"
            }
        },3000)
    }

 

실행해 보면 TextView를 직접 변경해주는 코드 없이 Handler()를 이용해서 3초 후 그냥 item.site의 값만 바꿔줬을 뿐인데, 뷰에서 알아서 감지한 후 값을 변경해주는 것을 볼 수 있다.

 


Observable을 공부하면서 실시간 데이터 관찰이라길래 어렵다고 생각했는데, 막상 실제로 해보니 그렇게 어렵지 않았다.

Git에 올라와 있는 소스코드를 보면서 천천히 이해하길 바란다.

Git 브랜치 중 DataBinding 브랜치로 들어가면 전체 소스코드를 확인할 수 있다.

 

https://github.com/kangmin1012/AndroidExcercise.git