Map / SwitchMap

최대환·2023년 12월 11일
0

Map / SwitchMap

이전 포스트에서는 LiveData의 값을 변경하는 방법에 대해 다루었는데, MainActivity에서 직접적으로 it 간의 산술 연산을 통해 값을 변경했습니다. 그러나 이 방법은 유지보수가 어려울 뿐만 아니라, 다른 뷰에서 재사용이 어렵다는 단점이 있습니다. 이번 포스트에서는 Map과 SwitchMap 함수를 활용하여 ViewModel 내에서만 값을 변경하는 방법을 소개하려고 합니다.

우선 map과 switchMap을 이용하기 위해 gradle에서 아래 코드를 임포트 받아준다.

build.gradle
implementation("androidx.lifecycle:lifecycle-livedata-core:2.3.1")

그리고 뷰모델에 mapLiveDataswitchMapLiveData을 만들어준다. map과 switchMap은 모두 라이브데이터의 데이터변환을 돕는 함수지만, map은 liveData를 다른 값으로 바꿔주고 switchMap은 liveData를 다른 liveData로 바꿔준다. 그러기때문에 switchMap을 사용하면 MutableLiveData(count*count)을 리턴해준다

MainViewModel
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에서 mapLiveDataswitchMapLiveData라는 값을 관찰해주고 그에 맞게 결과값을 ui에 보여준다.

MainActivity
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()
        })
    }
}
activity_main.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">

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

아래 사진과 같이 잘 적용이된걸 볼 수 있다

profile
나의 개발지식 output 공간

0개의 댓글