다국어를 지원하는 앱이라면 문자열을 처리할 때 보통 strings.xml 에서 문자열을 가져와서 보여줍니다. strings.xml 파일로 대부분의 문자열을 처리할 수 있지만, 만약 영어처럼 단/복수가 구분된 경우에는 어떻게 처리를 해야 할까요? 이런 경우에는 안드로이드 리소스 중에 plurals 요소를 사용하면 편리하게 관리할 수 있습니다.
plurals 요소를 활용할 수 있는 예로는 one minute, 2 minutes이 있습니다.
먼저 plurals 요소를 사용하지 않고 string 요소를 사용한다면 어떻게 표기해야 할까요? 우선 strings.xml에 리소스를 만들어 줍니다.
<string name="time_minute">%d분</string>
<string name="time_minutes">%d분</string>
<string name="time_minute">one minute</string>
<string name="time_minutes">%d minutes</string>
단수, 복수를 구분하여 2개의 리소스를 만든 뒤, 소스 코드에서 개수에 따라 분기를 하여 표기해줍니다.
fun getMinuteText(minute: Int): String {
return if (minute == 1) {
resources.getString(R.string.time_minute)
} else {
resources.getString(R.string.time_minutes, minute)
}
}
위와 같은 방법으로 처리할 수 있지만, 몇 가지 마음에 들지 않는 부분이 있습니다. 우선 한국어는 단/복수를 구분하지 않기 때문에 time_minute와 time_minutes 리소스가 같습니다. 같은 리소스를 여러 개 만드는 불필요한 일을 해야 합니다. 또한 소스 코드 상에서 분기 처리하는 일도 마음에 들지 않습니다.
이제 plurals 요소를 활용하여 표기하는 방법을 알아보겠습니다. <item> 요소의 quantity 속성 값에 따라 다른 리소스를 설정해줍니다.
<plurals name="time_minute">
<item quantity="other">%d분</item>
</plurals>
<plurals name="time_minute">
<item quantity="one">one minute</item>
<item quantity="other">%d minutes</item>
</plurals>
소스 코드에서 해당 리소스에 접근할 때는 아래와 같이 해주면 됩니다.
fun getMinuteText(minute: Int): String {
return resources.getQuantityString(R.plurals.time_minute, minute, minute)
}
item 요소의 quantity는 아래와 같이 총 6개의 값을 사용할 수 있습니다.
quantity를 설정할 때는 주의할 점이 있습니다. plurals는 언어마다 숫자에 대한 표현이 문법적으로 다른 경우에만 사용 가능합니다. 다시 말하자면 단순한 if문과 같은 방식이 아닙니다. 스택오버플로우의 한 답변에 따르면 이는 Unicode Common Locale Data Repository(CLDR)라는 체계를 따르는 겁니다. 논리의 개념이 아닌 인간의 언어에 대한 개념으로 만들어진 체계라고 합니다.
따라서 아래의 리소스에서 "당일"이라는 문자열은 나올 수가 없습니다. 한국어는 단/복수를 구분하지 않기 때문에 무조건 other로만 취급하기 때문입니다.
<plurals name="day">
<item quantity="one">당일</item>
<item quantity="other">%d일</item>
</plurals>
참고
developer.android.com/guide/topics/resources/string-resource#Plurals
'Android' 카테고리의 다른 글
[Android] Sticky Header RecyclerView 응용하기 (0) | 2021.04.19 |
---|---|
[Android] LeakCanary로 메모리릭 잡기 (0) | 2021.04.17 |
[Android] Kotlin에서 LiveData의 null 허용 개선 - NonNullLiveData (2) | 2021.01.24 |
[Android] RecyclerView에 divider 넣기 - ItemDecoration (1) | 2021.01.16 |
[Android] LiveData setValue() vs postValue() (0) | 2021.01.15 |