참고 : 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}"