Question
How to Get Context in Jetpack Compose for Toast Messages in Kotlin
Question
I am using Jetpack Compose and want to show a Toast message when a button is clicked inside a composable item. In the older View-based approach, I would normally pass an Activity or Context, but I am not sure how to access it inside a composable.
Here is the code:
fun createListItem(itemIndex: Int) {
Padding(left = 8.dp, right = 8.dp, top = 8.dp, bottom = 8.dp) {
FlexRow(crossAxisAlignment = CrossAxisAlignment.Center) {
expanded(1.0f) {
Text("Item $itemIndex")
}
inflexible {
Button(
text = "Button $itemIndex",
style = ContainedButtonStyle(),
onClick = {
Toast.makeText(
this@MainActivity,
"Item name $itemIndex",
Toast.LENGTH_SHORT
).show()
}
)
}
}
}
}
How do I correctly get a Context in Jetpack Compose so I can pass it to Toast.makeText()?
Short Answer
By the end of this page, you will understand how Context works in Jetpack Compose, why this@MainActivity is usually not the right approach inside a composable, and how to use LocalContext.current to show a Toast safely and cleanly.
Concept
In Android, many APIs need a Context. A Toast is one of them. In the traditional View system, you often had direct access to an Activity, Fragment, or View, so getting a Context felt straightforward.
In Jetpack Compose, UI is written as composable functions. These functions are not class instances like Activity, so this usually does not refer to what you expect. That is why code such as this@MainActivity is often not available or not appropriate inside a composable.
Compose provides access to Android framework objects through Composition Locals. For Context, the standard way is:
val context = LocalContext.current
This gives you the current Android Context for the composable tree. You can then use it with APIs like:
Toast.makeText(...)- reading resources
- accessing system services
- starting activities in some cases
Why this matters:
- It keeps composables decoupled from a specific
Mental Model
Think of Context as your app's environment pass.
In the old View system, you were often standing inside a room that already had a label like MainActivity, so grabbing the environment was easy.
In Compose, a composable is more like a recipe for UI, not a room itself. Since the recipe is not the activity, it does not automatically have direct access to MainActivity.
LocalContext.current is like asking the Compose system:
“What Android environment am I currently running in?”
Compose then hands you the right Context for that part of the UI tree.
Syntax and Examples
The basic Compose syntax is:
val context = LocalContext.current
Then use it in your click handler:
Toast.makeText(context, "Hello", Toast.LENGTH_SHORT).show()
Example
@Composable
fun CreateListItem(itemIndex: Int) {
val context = LocalContext.current
Row(modifier = Modifier.padding(8.dp)) {
Text(
text = "Item $itemIndex",
modifier = Modifier.weight(1f)
)
Button(
onClick = {
Toast.makeText(
context,
"Item name $itemIndex",
Toast.LENGTH_SHORT
).show()
}
) {
Text("Button $itemIndex")
}
}
}
Why this works
LocalContext.currentgives the current AndroidContext- The
contextvalue can be used inside the button'sonClick
Step by Step Execution
Consider this composable:
@Composable
fun ToastButton(itemIndex: Int) {
val context = LocalContext.current
Button(onClick = {
Toast.makeText(context, "Clicked item $itemIndex", Toast.LENGTH_SHORT).show()
}) {
Text("Show Toast")
}
}
Here is what happens step by step:
- Compose starts building the UI for
ToastButton. val context = LocalContext.currentasks Compose for the current AndroidContext.- Compose stores that
contextvalue for this composition. - The
Buttonis displayed on screen. - The user taps the button.
- The
onClicklambda runs. Toast.makeText(context, "Clicked item $itemIndex", Toast.LENGTH_SHORT)creates a toast..show()displays the toast on screen.
Trace example
If itemIndex is 3, then:
Real World Use Cases
Getting Context in Compose is useful in many real apps, not just for Toast.
Common use cases
-
Showing toast messages
- Example: "Profile saved"
- Example: "Failed to load data"
-
Accessing resources
- Reading strings, dimensions, or other Android resources
-
Using Android services
- Clipboard
- Connectivity manager
- Notification manager
-
Starting Android components
- Launching another activity with an
Intent
- Launching another activity with an
-
Working with files or preferences
- Accessing app storage helpers that need a
Context
- Accessing app storage helpers that need a
Example scenario
In a shopping app:
- User taps Add to cart
- A toast says Item added to cart
- The composable uses
LocalContext.currentto create that toast
In a form screen:
- User presses Submit
- Validation fails
Real Codebase Usage
In real projects, developers often use Context in Compose with a few common patterns.
1. Direct UI feedback
For quick feedback such as a toast:
val context = LocalContext.current
Button(onClick = {
Toast.makeText(context, "Saved", Toast.LENGTH_SHORT).show()
}) {
Text("Save")
}
2. Keep business logic out of composables
A composable should usually handle UI actions, while business logic stays in a ViewModel or use-case layer.
Good pattern:
- ViewModel decides what happened
- Composable decides how to display it
For example, a ViewModel emits a success event, and the composable shows a toast using context.
3. Guard clauses before using Context-based APIs
Example:
if (itemIndex < 0) return
This prevents invalid actions before trying to show a toast or start another Android action.
4. Event handling pattern
A common real-world pattern is:
- user clicks button
- UI sends event
- state updates
- composable reacts
- composable uses
LocalContext.currentfor Android-only UI work
Common Mistakes
1. Using this@MainActivity inside a composable
Broken example:
@Composable
fun MyItem() {
Button(onClick = {
Toast.makeText(this@MainActivity, "Hello", Toast.LENGTH_SHORT).show()
}) {
Text("Click")
}
}
Why it is a problem:
- A composable is not the activity
thismay not refer to what you think- It tightly couples the composable to one activity
Use this instead:
@Composable
fun MyItem() {
val context = LocalContext.current
Button(onClick = {
Toast.makeText(context, "Hello", Toast.LENGTH_SHORT).show()
}) {
Text("Click")
}
}
2. Forgetting @Composable
Broken example:
fun MyItem() {
context = LocalContext.current
}
Comparisons
| Approach | How it gets Context | Best use case | Notes |
|---|---|---|---|
LocalContext.current | Read from Compose composition | Inside composables | Standard Compose approach |
this@MainActivity | Reference the activity directly | Rarely inside Compose UI | Tightly coupled and often not available |
Passing Context as a parameter | Sent from caller | Special reusable APIs | Can work, but often unnecessary in Compose |
applicationContext | App-level context | Long-lived, app-wide tasks | Not always suitable for UI-specific work |
LocalContext.current vs passing
Cheat Sheet
val context = LocalContext.current
Toast.makeText(context, "Hello", Toast.LENGTH_SHORT).show()
Rules
- Use
LocalContext.currentinside composables - Add
@Composableto the function readingLocalContext.current - Prefer
Contextover directly referencing anActivity - Use
Contextonly for Android-specific work
Common import
import androidx.compose.ui.platform.LocalContext
Basic pattern
@Composable
fun MyButton() {
val context = LocalContext.current
Button(onClick = {
Toast.makeText(context, "Clicked", Toast.LENGTH_SHORT).show()
}) {
Text("Click")
}
}
Edge cases
FAQ
How do I get Context in Jetpack Compose?
Use LocalContext.current inside a composable.
Can I use this@MainActivity inside a composable?
Usually you should not. Composables are not activity instances, and this creates tight coupling.
Why does Toast.makeText() need a context?
Toast is an Android framework API and needs the current app or UI environment to display itself.
Does LocalContext.current return an Activity?
Not necessarily. It returns a Context. Sometimes that context is backed by an activity, but you should not assume that unless required.
Can I call LocalContext.current outside a composable?
No. It must be used from a composable function.
Is it okay to show a toast directly in a composable click handler?
Yes, for simple UI feedback this is normal. For larger app logic, keep business decisions outside the composable.
What is the modern Compose way to replace old layout code like FlexRow?
Modern Compose usually uses Row, , and APIs instead of older layout syntax.
Mini Project
Description
Build a small Compose screen that shows a list of items, each with a button. When the user taps a button, a toast should display the item number. This demonstrates how to access Context correctly in Jetpack Compose and use it inside event handlers.
Goal
Create a reusable composable list item that uses LocalContext.current to show a toast when its button is clicked.
Requirements
- Create a composable function for a single list item.
- Display the item number as text.
- Add a button for each item.
- Show a toast with the item number when the button is clicked.
- Use
LocalContext.currentinstead of directly referencing an activity.
Keep learning
Related questions
Accessing Kotlin Extension Functions from Java
Learn how Kotlin extension functions are compiled and how to call them correctly from Java with clear examples and common pitfalls.
Allow HTTP and HTTPS in Android 9 Pie with Network Security Configuration
Learn how Android 9 Pie handles cleartext HTTP traffic and how to allow HTTP and HTTPS safely using network security config.
Android AlarmManager Example: Scheduling Tasks with AlarmManager
Learn how to use Android AlarmManager to schedule tasks, set alarms, and handle broadcasts with a simple beginner example.