kotlinandroid-jetpack-composeandroid-compose-textfield

How to get stringResource if not in a composable function


I have a Jetpack Compose app that uses stringResource everywhere and it works great for localization.

But, I have a few functions that are no Composable Functions and I would like to retrieve the string from the resources. When I try to use stringResource in those functions it tells me it can only be used in a composable.

So, how do I get a string from a resource if I am not a composable function?


Solution

  • Not sure if I understand it correctly, but is it like this?

    @Composable
    fun Composable() {
    
        val context = LocalContext.current
        val someString = NonComposable(context)
    }
    
    fun NonComposable(context: Context): String =
        context.resources.getString(R.string.app_name)
    

    Recommendation: You can also define a sealed class that has 2 types where you can supply your intended string parameter, an actual String value and a String resource where you can specify how they're going to be resolved.

    UiText

    sealed class UiText {
    
    data class StringValue(val str: String): UiText()
    
    class StringResource(
        @StringRes val resourceId: Int,
        vararg val args: Any
    ): UiText()
    
    @Composable
    fun asString(): String {
        return when (this) {
            is StringValue -> {
                str
            }
            is StringResource -> {
                stringResource(id = resourceId, formatArgs = args)
            }
        }
    }
    

    Sample usage scope:

    Inside your ViewModel where you can simply supply the id of the string resource

    var stringResourceVariable = UiText.StringResource(R.string.some_string_resource)
    

    Then in your Composable

    viewModel.stringResourceVariable.asString()
    

    you can simply invoke asString and it will be resolved depending on what type of UiText string you supplied.

    The benefit of having this approach, is you won't have any problems supplying string resources in your ViewModel.