Android, iOS

[MVVM 정복] 2. SnackbarMessage, BaseViewModel, BaseActivity

미스터머글 2020. 5. 18. 17:46
728x90
반응형

코드는 내 깃헙을 참고하면 된다. 커밋 로그와 블로그 포스팅 제목이 유사하게 따라간다.

 

SnackbarMessage

SnackbarMessage는 SingleLiveEvent이다. 앞 포스팅에 있는 그 SingleLiveEvent이다. 

Snackbar에 보여주고 싶은 메세지가 있다면 이 이벤트의 value에 원하는 메시지를 담으면 된다.

 

class SnackbarMessage : SingleLiveEvent<Int>() {
    fun observe(owner: LifecycleOwner, observer: (Int) -> Unit) {
        super.observe(owner, Observer {
            it?.run {
                observer(it)
            }
        })
    }
}

 

위의 super.observe는 SingleLiveEvent에 있는 override fun observe이며 SnackbarMessage의 value가 변경되면 observer(it)이 수행된다. 여기서 람다식이 많이 나오는데 다른 블로그에서 설명을 잘 해두었다. 참고하길 바란다. 또한 LifecycleOwner라는 것이 등장하는데 그건 여기서 확인해보도록 하자.

 

LifecycleOwner

public interface LifecycleOwner {
    /**
     * Returns the Lifecycle of the provider.
     *
     * @return The lifecycle of the provider.
     */
    @NonNull
    Lifecycle getLifecycle();
}

단일 메소드를 가지는 이 인터페이스는 AppCompatActivity 내부에 존재하고 있다. 그 외에도 많은 뷰에 포함되어 있다. 이 인터페이스는 해당 뷰가 어떤 라이프사이클에 도달해 있는지 알 수 있다. 이 경우에는 Observer가 라이프사이클을 확인할 수 있어서 적절한 타이밍에 초기화 혹은 Cleanup을 진행할 수 있다.

 

BaseViewModel

우리가 알아야하는 ViewModel은 두가지이다.

  • AAC의 ViewModel
    • UI와 관련된 데이터를 저장/관리
    • 스크린 회전을 할 때, View의 객체가 재생성되어서 데이터를 다시 갱신해야 하는데 이 변화에도 데이터가 잘 보존되도록 해준다.
    • 액티비티 스코프의 싱글톤객체처럼 사용할 수 있다. 프래그먼트 사이에서 viewModel을 이용하여 데이터를 쉽게 공유할 수 있다.
    • viewModel내부에 액티비티, 프레그먼트, 뷰에 대한 컨텍스트를 저장해서는 안된다.
    • viewModel은 기기의 구성이 변경될때만 유지. 백버튼이나 , 최근목록에서 앱을 종료했을때는 어떠한 처리도 기대할 수 없다.
  • MVVM의 ViewModel
    • 비즈니스 로직이 들어가는 부분. 데이터를 가공해서 View에 보여지게 Model로 바꾸는 역할이다.
    • ViewModel에서 직접 View에 데이터를 전달하지 않는다. Data binding을 통해 View가 갱신된다.

 

안드로이드에서 Data binding을 하는 방법은 세가지가 있다.

  • 직접 Observer패턴을 이용한 Data binding을 구현
  • 안드로이드에서 제공하는 ViewModel을 사용
  • RxJava2를 사용하는 방법 (요즘 트렌드)

스낵바를 처리하는 로직이 왜 ViewModel에 있을까? 보통 특정 데이터가 어떤 조건에 부합할 때 토스트나 스낵바가 뜨기 마련이다. 그렇다면 해당 데이터는 obobserve되어 있어야 하기에 ViewModel에서 처리를 하는 것이다. observeSnackbarMessage를 사용하는 BaseActivity도 살펴보자.

 

BaseActivity

  • lateinit var viewDataBinding: T
    • 데이터바인딩으로 뷰(xml)를 갱신할 수 있도록 세팅
  • abstract val layoutResourceId: Int
    • setContentView로 호출할 Layout의 리소스 Id.
    • ex) R.layout.activity_sbs_main
  • abstract val viewModel: R
    • viewModel 로 쓰일 변수.
  • abstract fun initStartView()
    • 레이아웃을 띄운 직후 호출.
    • 뷰나 액티비티의 속성 등을 초기화.
    • ex) 리사이클러뷰, 툴바, 드로어뷰..
  • abstract fun initDataBinding()
    • 두번째로 호출. 데이터 바인딩 및 rxjava 설정.
    • ex) rxjava observe, databinding observe..
  • abstract fun initAfterBinding()
    • 바인딩 이후에 할 일을 여기에 구현.
    • 그 외에 설정할 것이 있으면 이곳에서 설정.
    • 클릭 리스너도 이곳에서 설정.

마지막으로, snackbarObserving이 있다. 앞에서 언급한 것처럼 ViewModel에서 라이프사이클 상의 뷰를 관측하기 위해 존재하며, 특정 이벤트가 발생했을 때 스낵바를 띄우기 위함이다.

 

참고자료
https://tourspace.tistory.com/24
https://www.bsidesoft.com/5999
https://developer.android.com/topic/libraries/architecture/lifecycle?hl=ko
728x90
반응형