안드로이드 코틀린

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

teamnova 2023. 2. 6. 12:00
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())

 

결과는 다음과 같습니다.