본문 바로가기
안드로이드 코틀린

[Kotlin][Android] View Model에서 안드로이드 문자열 관리하기

by teamnova 2023. 2. 6.
728x90

안녕하세요.

오늘은 뷰모델에서 문자열(string)을 관리하는 하나의 방법에 대해 알아보겠습니다. 

 

viewmodel은 UI 레이어에 대한 state holder 역할을 합니다. 

그에 따라 view에서 쉽게 사용할 수 있는 UI state 및 model을 준비합니다. 

여기에는 표시하고자 하는 문자열도 포함이 됩니다. 

 

그러나 

뷰모델에서 문자열들을 관리할 때, R class를 사용해 Android Resources에 접근하려 할 때 문제가 생깁니다. 

왜냐하면 뷰모델은 Context에 접근할 수 없기 때문에 문자열을 가져와 사용할 수 없습니다. 

 

이를 해결하기 위해 아래의 클래스를 사용할 수 있습니다. 

이 클래스는 문자열 리소스 ID와 매개변수 목록을 파라미터로 받습니다. 

class StringResWithParams(
    @StringRes private val resId: Int,
    private vararg val params: Any
) {

    fun toString(context: Context): String =
        context.getString(resId, *processParams(context).toTypedArray())

    private fun processParams(context: Context) =
        params.map {
            when(it){
                is Int -> try {
                    context.resources.getString(it)
                } catch (ex: Resources.NotFoundException) {
                    it
                }
                is StringResWithParams -> it.toString(context)
                else -> it
            }
        }
}

 

아래와 같이 세 가지 문자열을 사용하는 것을 예로 들어 보겠습니다. 

<string name="car_string">Car: %1$s, year: %2$d</string>
<string name="ferrari_string">Ferrari %1$s</string>
<string name="ferrari_f40">F40</string>

 

뷰모델에서 다음과 같이 문자열을 작성할 수 있으며 livedata 또는 flow를 사용하여 뷰에 알릴 수 있습니다.

val stringResWithParams = StringResWithParams(
    resId = R.string.car_string,
    params = arrayOf(
        StringResWithParams(
            resId = R.string.ferrari_string,
            params = arrayOf(
                R.string.ferrari_f40
            )
        ), 2008
    )
)

 

액티비티 또는 프래그먼트에서는 다음과 같이 작성해줍니다.

binding.textView.text = stringResWithParams.toString(requireContext())

 

결과는 다음과 같습니다.