# 2021/12/13

silmxmail·2022년 1월 7일
0

1일1문서

목록 보기
5/17

https://medium.com/ozan-superapp/a-way-of-using-android-data-binding-library-in-form-pages-cdfd08bc7d22

참고 : https://developer.android.com/topic/libraries/data-binding/two-way?hl=ko

한 페이지에서 상태에 따른 버튼 on/off를 간편하게 하는 방법

ViewState를 이용하자.

먼저 values를 가지고있을 ViewState를 생성하자.

@Suppress("ConstructorParameterNaming")
data class MainFormViewState(
    private var _name: String = "",
    private var _surname: String = "",
    private var _age: String = ""
) : BaseObservable() {

    var name: String
        @Bindable get() = _name
        set(value) {
            _name = value
            notifyPropertyChanged(BR.name)
        }
    var surname: String
        @Bindable get() = _surname
        set(value) {
            _surname = value
            notifyPropertyChanged(BR.surname)
        }
    var age: String
        @Bindable get() = _age
        set(value) {
            _age = value
            notifyPropertyChanged(BR.age)
        }
}

그 후로 ViewModel을 생성하고 ViewState를 관찰할 준비를 하자.

class MainViewModel : ViewModel() {

    private val formViewStateLiveData: MutableLiveData<MainFormViewState> = MutableLiveData()

    fun getFormViewStateLiveData(): LiveData<MainFormViewState> =
        formViewStateLiveData

    private fun setFormViewStateLiveData(viewState: MainFormViewState) {
        formViewStateLiveData.value = viewState
    }

    fun initData() {
        setFormViewStateLiveData(MainFormViewState())
    }

    fun submitForm() {
        val formValues = formViewStateLiveData.value
        Log.v("FormSample", "Name : ${formValues?.name}")
        Log.v("FormSample", "Surname : ${formValues?.surname}")
        Log.v("FormSample", "Age : ${formValues?.age}")
    }
}

여기서 setForm~을 통해 formViewState의 데이터를 초기화시켜준다.

이후 xml에 데이터 바인딩을 할 준비를 한다.

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

        <variable
            name="formViewState"
            type="com.faskn.databindingexample.MainFormViewState" />

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

            <com.google.android.material.textfield.TextInputLayout
                style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/name">

                <com.google.android.material.textfield.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:backgroundTint="@android:color/white"
                    android:text="@={formViewState.name}" />

            </com.google.android.material.textfield.TextInputLayout>

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

액티비티/Fragment 에서 뷰모델을 이용하여 데이터를 연결시켜준다.

class MainActivity : AppCompatActivity() {

    //.. other stuffs

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)

        viewModel.initData()

        binding.buttonContinue.setOnClickListener {
            viewModel.submitForm()
        }

        viewModel.getFormViewStateLiveData().observe(this, { viewState ->
            setFormViewState(viewState)
        })
    }

    private fun setFormViewState(viewState: MainFormViewState) {
        binding.formViewState = viewState
        binding.executePendingBindings()
    }
}

그리고 메서드를 하나 설정해준다. 이건 조건이 충족되었는지를 확인시켜준다.

@Bindable
    fun isContinueButtonEnabled(): Boolean {
        notifyPropertyChanged(BR.continueButtonEnabled)
        return name.isEmpty().not() &&
                surname.isEmpty().not() &&
                age.isEmpty().not()
    }

그리고 xml의 버튼쪽에 다음을 넣는다.

android:enabled="@{formViewState.continueButtonEnabled}"
profile
러닝커브를 따라서 등반중입니다.

0개의 댓글