이전 포스트에서는 LiveData의 값을 변경하는 방법에 대해 다루었는데, MainActivity에서 직접적으로 it 간의 산술 연산을 통해 값을 변경했습니다. 그러나 이 방법은 유지보수가 어려울 뿐만 아니라, 다른 뷰에서 재사용이 어렵다는 단점이 있습니다. 이번 포스트에서는 Map과 SwitchMap 함수를 활용하여 ViewModel 내에서만 값을 변경하는 방법을 소개하려고 합니다.
우선 map과 switchMap을 이용하기 위해 gradle에서 아래 코드를 임포트 받아준다.
implementation("androidx.lifecycle:lifecycle-livedata-core:2.3.1")
그리고 뷰모델에 mapLiveData
와 switchMapLiveData
을 만들어준다. map과 switchMap은 모두 라이브데이터의 데이터변환을 돕는 함수지만, map은 liveData를 다른 값으로 바꿔주고 switchMap은 liveData를 다른 liveData로 바꿔준다. 그러기때문에 switchMap을 사용하면 MutableLiveData(count*count)
을 리턴해준다
class MainViewModel : ViewModel() {
private var _mutableCount = MutableLiveData(0)
val liveCount : LiveData<Int>
get() = _mutableCount
val mapLiveData = liveCount.map {
it+it
}
val switchMapLiveData = liveCount.switchMap {
changeValue(it)
}
fun setLiveDataValue(count : Int) {
_mutableCount.value = count
}
fun changeValue(count : Int) : MutableLiveData<Int> {
val testLiveData = MutableLiveData(count*count)
return testLiveData
}
}
MainActivity
에서 mapLiveData
와 switchMapLiveData
라는 값을 관찰해주고 그에 맞게 결과값을 ui에 보여준다.
class MainActivity : AppCompatActivity() {
private lateinit var binding : ActivityMainBinding
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
binding.btnArea.setOnClickListener {
val count = binding.inputArea.text.toString().toInt()
viewModel.setLiveDataValue(count)
}
viewModel.mapLiveData.observe(this, Observer {
binding.resultArea1.text = it.toString()
})
viewModel.switchMapLiveData.observe(this, Observer {
binding.resultArea2.text = it.toString()
})
}
}
<?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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- 10 -> 10 + 10 -->
<!-- 10 -> 10 x 10 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/inputArea"
android:hint="0"
android:textSize="50sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btnArea"
android:text="btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/resultArea1"
android:text="0"
android:textSize="50sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/resultArea2"
android:text="0"
android:textSize="50sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
아래 사진과 같이 잘 적용이된걸 볼 수 있다