Skip to content

Instantly share code, notes, and snippets.

@evjava
Created July 25, 2022 13:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evjava/b213f01ac9cdd79d4fdea2e0cf8f4bbc to your computer and use it in GitHub Desktop.
Save evjava/b213f01ac9cdd79d4fdea2e0cf8f4bbc to your computer and use it in GitHub Desktop.
Abstracting Android text resources
//// inspired by https://hannesdorfmann.com/abstraction-text-resource/
// TextResource.kt
sealed class TextResource {
class Raw(val str: String) : TextResource()
class TextId(val id: Int) : TextResource()
class TextIdArgString(val id: Int, val arg: String) : TextResource()
class TextIdArgInt(val id: Int, val arg: Int) : TextResource()
class TextIdArgId(val id: Int, val argRes: Int) : TextResource()
class TextList(val texts: List<TextResource>) : TextResource()
class TextIdArgRes(val id: Int, val arg: TextResource) : TextResource()
class TextDate(val pattern: String, val date: Date) : TextResource()
companion object {
val Int.asResource: TextResource
get() = TextId(this)
val String.asResource: TextResource
get() = Raw(this)
fun Int.asResource(arg: String): TextResource {
return TextIdArgString(this, arg)
}
fun Int.asResource(arg: TextResource): TextResource {
return TextIdArgRes(this, arg)
}
fun String.asResource(date: Date): TextResource {
return TextDate(this, date)
}
val List<TextResource>.asResource: TextResource
get() = TextList(this)
}
}
// ComposeUtil.kt
@Composable
fun TextResource.render(): String {
return when (this) {
is TextResource.TextId -> stringResource(id)
is TextResource.TextIdArgInt -> stringResource(id, arg)
is TextResource.TextIdArgString -> stringResource(id, arg)
is TextResource.Raw -> str
is TextResource.TextIdArgId -> stringResource(id, stringResource(argRes))
is TextResource.TextList -> texts.map { it.render() }.joinToString(separator = "\n")
is TextResource.TextIdArgRes -> stringResource(id, arg.render())
is TextResource.TextDate -> formatDate(pattern, date)
}
}
// ContextExt.kt
fun Context.render(res: TextResource): String {
return when (res) {
is TextResource.TextId -> getString(res.id)
is TextResource.TextIdArgInt -> getString(res.id, res.arg)
is TextResource.TextIdArgString -> getString(res.id, res.arg)
is TextResource.Raw -> res.str
is TextResource.TextIdArgId -> getString(res.id, getString(res.argRes))
is TextResource.TextList -> res.texts.joinToString(separator = "\n") { render(it) }
is TextResource.TextIdArgRes -> getString(res.id, render(res.arg))
is TextResource.TextDate -> formatDate(res.pattern, res.date)
}
}
fun Context.formatDate(pattern: String, date: Date): String {
return SimpleDateFormat(pattern, getLocale()).format(date)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment