Home > Mobile >  How to set a custom Context in Jetpack Compose?
How to set a custom Context in Jetpack Compose?

Time:11-03

I have run into an issue with Jetpack Compose. In my application's old classes (activity and fragment) I am using a custom Context wrapper for my custom Resources wrapper. This is because string resources values are downloaded from a server; the Strings resource files do contain string IDs, their values are empty and are replaced by the server's values.

In activities and fragments I can simply replace the context in getContext() or attachBaseContext(newBase: Context?) methods, but how do I do this in Jetpack Compose?

Jetpack Compose does have these Context methods: LocalConfiguration.current and LocalContext.current. I love how straightforward this is, but I was not able to find where this Context object is inited. At first, I thought it was in the parent Activity in attachBaseContext() method when I set content, but this code does not seem to be useful:

@AndroidEntryPoint
class MyComposeActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContent {
        ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
            MyComposeActivityScreen()
        }
    }
}

override fun attachBaseContext(newBase: Context?) {
    val language = Locale(Utils.getLanguage(newBase))
    super.attachBaseContext(MyCustomContextWrapper.wrap(MyCustomResourcesContextWrapper(newBase), language))
}

CodePudding user response:

You can try specifying the context manually with CompositionLocalProvider:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    updateComposeView(this)
}

override fun attachBaseContext(newBase: Context?) {
    super.attachBaseContext(newBase)
    updateComposeView(newBase ?: this)
}

fun updateComposeView(context: Context) {
    setContent {
        CompositionLocalProvider(
            LocalContext provides context
        ) {
            ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
                MyComposeActivityScreen()
            }
        }
    }
}

Also a more Compose way to solve the original problem is to create your own string holder, something like LocalStrings, kind of as shown in this answer.

  • Related