Android

[Android] MVVM, LiveData, ViewModel, Databinding 프로젝트에 적용

dev_zoe 2021. 10. 19. 00:19
반응형

build.gradle

        val lifecycle_version = "2.4.0-rc01"

       
// ViewModel
        implementation
("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")
       
// LiveData
        implementation
("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")

 

https://developer.android.com/jetpack/androidx/releases/lifecycle?hl=ko#declaring_dependencies 

 

Lifecycle  |  Android 개발자  |  Android Developers

Lifecycle 수명 주기 인식 구성요소는 활동 및 프래그먼트와 같은 다른 구성요소의 수명 주기 상태 변경에 따라 작업을 실행합니다. 이러한 구성요소를 사용하면 잘 구성된 경량의 코드를 만들어

developer.android.com

여기서 버전 확인가능

 

1. 레이아웃

  • Databinding을 사용하려면 반드시 최상위 태그를 layout 태그로 감싸야함
  • 여기서 ViewModel도 사용할 시에 하위에 <data> 태그를 추가하여 ViewModel을 지정함
  • <data> 하위의 <import> 태그로 안드로이드의 다양한 속성을 가져와 Databinding에서 활용 할 수 있음
<!-- Databinding을 사용하려면 반드시 최상위 태그를 layout 태그로 감싸고,
viewModel을 사용하려면 하위에 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>
        <import
            type="android.view.View"/>
        <variable
            name="viewModel"
            type="com.my.android.src.login.LoginViewModel" />
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".src.login.email.EmailLoginActivity">
        .... 중략

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

 

2. ViewModel 클래스

//ViewModel의 일부
abstract class MainViewModel : ViewModel()
//mutablelivedata -> 변경이 가능한 데이터 (네이밍룰로 앞에 언더바를 붙여줌)
 private val _isVisible = MutableLiveData<Boolean>() //visiblity

    //livedata -> 변경이 불가능한 데이터
    val isVisible : LiveData<Boolean>
        get() = _isVisible
        
//초기값 설정
    init {
        _isVisible.value = false
    }
    
//값을 세팅해주는 함수 정의
    fun setinVisible(){
        _isVisible.value = false
    }

    fun setVisible(){
        _isVisible.value = true
    }

 

3. Activity

  • DatabindingUtil을 이용하여 SetContentView
  • lifecycleOwner를 자기 자신으로 지정해줌
    • LifeCycleOwner란? 말그대로 생명주기를 가지고있는 주체.
    • LiveData는 앱의 생명주기를 인식하고 있으므로, databinding이 livedata와 같이 쓰려면 DataBinding의 생명주기를 가지고 있으면서 관찰할 주체를 정해줘야함 (여기서는 자기 자신이 생명주기 소유자이므로 this로 지정)
//Activity 일부   
   
   private lateinit var binding: ViewDataBinding
   
   override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.lifecycleOwner = this
    }

 

4. 액티비티에서 viewModel.setVisible -> ViewModel의 데이터가 바뀜(MutableLiveData) -> 뷰에 반영

  • 즉, ViewModel이 LiveData의 변화를 감지하면, Model에게 값을 바꾸라고 명령
  • Model이 값을 바꾸면 ViewModel에게 전달
  • View는 이러한 ViewModel을 감시하고 있으면서, 모델의 변화가 감지될때마다 즉시 변화
        <!-- viewModel을 사용하는 일부 부분 -->
        <ImageView
            android:id="@+id/imgEmailLoginCheck"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:visibility="@{viewModel.isVisible() ? View.VISIBLE : View.INVISIBLE}"
            app:layout_constraintBottom_toBottomOf="@+id/edtLoginEmail"
            app:layout_constraintEnd_toEndOf="@+id/edtLoginPassword"
            app:layout_constraintTop_toTopOf="@+id/edtLoginEmail"
            app:srcCompat="@drawable/ic_check_m"
            tools:visibility="visible" />
        binding.edtLoginEmail.addTextChangedListener(object:TextWatcher{
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun afterTextChanged(p0: Editable?) {
                if (ValidationRegex.isRegexEmail(binding.edtLoginEmail.text.toString().trim())){
                    //viewModel의 값 변경 -> View가 이를 감시하여 변화함
                    //viewModel의 visible = true로 변경
                    emailViewModel.setVisible()
                }
                else{
                //visible = false로 변경
                    emailViewModel.setinVisible()
                }
                checkValid()
            }
        })

 

5. 결과물

 

Reference

https://fornewid.medium.com/android-ktx-databinding%EC%9C%BC%EB%A1%9C-view-layer-%EC%BD%94%EB%93%9C-%EC%A4%84%EC%9D%B4%EA%B8%B0-%EF%B8%8F-690cd61aec3d

반응형