How to get Context in Jetpack Compose
Asked Answered
P

12

189
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(
                    "Button $itemIndex",
                    style = ContainedButtonStyle(),
                    onClick = {
                        Toast.makeText(
                            this@MainActivity,
                            "Item name $itemIndex",
                            Toast.LENGTH_SHORT
                        ).show()
                    })
            }
        }
    }
}

I try to make Toast in a normal way. but I got the error I tried a lot of multiples source but failed.

Protanopia answered 7/11, 2019 at 7:5 Comment(2)
You might want to explain exactly what your problem was. I have used Toast in onClick handlers in Compose without a problem. If you were getting a compile error, please provide the complete details of the error. If you were getting a runtime error, please edit your question and post the stack trace.Rosalba
FYI: while the answers below are valid, the compose team now recommends using Snackbar over Toast in Compose: kotlinlang.slack.com/archives/CJLTWPH7S/….Carew
K
366

Update March 2021: The previous answer has been deprecated. You should now use:

val context = LocalContext.current

Previous answer for reference:

You can access to context with define ambientContext.

Example:

val context = ContextAmbient.current
Kapoor answered 13/11, 2019 at 9:46 Comment(7)
compose is declarative & as a tree, so if you have complex trees and you need some state that could not provided from root component, you can use ambient or memoKapoor
Is there any doc that explains the use of this unaryPlus operator? I can't find anything solid to understand what it is and how to use it @RakaJointworm
When I add val context = +ambient(ContextAmbient) to Clickable then get java.lang.IllegalStateException: Composition requires an active composition contextManton
please show your code (by gist.github.com) @AlexZezekaloKapoor
@RakaAdiNugroho I found out that I used a wrong place for getting context: firstly I wrote <code>val context = +ambient(ContextAmbient)<code> inside Clickable and it was the reason of that exception. Then I put this line out of the Clickable to the head of the function and everything became Ok. My fault.Manton
LocalContext.current can not be used in coroutine scope. This happens typically, when Android forces you to do something in a different thread, than the UI thread.Tish
I haven't seen this explicitly stated, but it appears Ambient has been removed/rename something else? I found this: lcdsmao.dev/… describing what it was. This seems related: developer.android.com/jetpack/androidx/releases/compose-runtime Renamed Ambients to match the Ambient -> CompositionLocal rename. Ambients used to be named AmbientFoo, now CompositionLocals are named LocalFoo. (I2d55d) I found ambients in old sample code: github.com/android/compose-samples/tree/main/JetchatSpurn
A
84

ContextAmbient and AmbientContext has been deprecated.

You can replace them with LocalContext

Example:

val context = LocalContext.current
Alerion answered 12/2, 2021 at 13:56 Comment(3)
How can I use this val context = LocalContext.current as a global variable in my Activity?Edelweiss
@gauravkumar I think the most you can do is declaring it as the first line in setContent method because it only works inside composable function. If you need a context outside setContent, just use this.Ripply
Android changes faster than the speed of light.😁. I have never used ContextAmbient and AmbientContext in my life.Riobard
I
38

ContextAmbient.current is deprecated as of alpha-09.

AmbientContext.current is deprecated. I think as of alpha-11.

LocalContext.current is how you get the context in a composable now.

Isogamy answered 23/12, 2020 at 19:30 Comment(0)
M
33

The way to do this has been updated. It's now:

val context = LocalContext.current

LocalContext docs

Misconstruction answered 9/3, 2020 at 20:50 Comment(0)
J
32

LocalContext.current - is the right approach. But the problem is you can't use LocalContext.current inside @Composable function

You need to create separate function to use Context

Sample code

@Composable
fun DoneButton() {
    val context = LocalContext.current
    Button(onClick = { showToast(context, "Button clicked")}) {
        Text(name = "Done")
    }
}

fun showToast(context: Context, msg: String) {
    Toast.makeText(context, msg, Toast.LENGTH_LONG).show()
}
Joyajoyan answered 5/7, 2021 at 10:48 Comment(0)
T
31

ContextAmbient and AmbientContext is deprecated

Update

Now Jetpack way to do this has been updated. It's now:

val context = LocalContext.current
Tribute answered 7/11, 2019 at 7:51 Comment(2)
What about Application context?Monied
@Monied Once you have the local context, context.getApplicationContext()Hamza
P
14

ContextAmbient.current has been deprecated, use val context = LocalContext.current instead.

Piccard answered 23/12, 2020 at 15:24 Comment(0)
H
9

Some useful if you need get context as Activity from last Android Studio template:

val view = LocalView.current
(view.context as Activity).<activity method>

Better solution

fun Context.getActivity(): Activity? = when (this) {
    is Activity -> this
    is ContextWrapper -> baseContext.getActivity()
    else -> null
}

val activity = LocalContext.current.getActivity()
Hospers answered 20/11, 2021 at 0:29 Comment(2)
It is not safe as the context may not be an activity.Pareto
@EmadRazavi Agree, I updated my answerHospers
N
6

For getting context in jetpack compose:

val context = ContextAmbient.current

Working on 0.1.0-dev14

How to use it in TOAST:

@Composable
fun cardViewImplementer(item: Int) {
   val context = ContextAmbient.current
   Card(
     shape = RoundedCornerShape(10.dp),
     modifier = Modifier.padding(10.dp)
   ) {
     Box(
        modifier = Modifier
            .fillMaxWidth()
            .drawShadow(5.dp)
            .clickable(onClick = {
                Toast.makeText(context, "Clicked $item", Toast.LENGTH_SHORT).show()
            }), children = {

        })
}

For accessing the Resource:

Text("Read this string: "+context.getString(R.string.name))
Necrotomy answered 25/6, 2020 at 11:41 Comment(0)
M
5

Issues with compose_version = '1.0.0-alpha12' ? AmbientContext is now LocalContext

Michaelamichaele answered 24/2, 2021 at 21:31 Comment(0)
D
3
val context = LocalContext.current
Toast.makeText(context,"Hello Compose",Toast.LENGTH_LONG).show()
Dubious answered 16/4, 2021 at 19:59 Comment(0)
E
1

You can use the LocalUriHandler:

val handler = LocalUriHandler.currenthandler 

Button( 
    onClick = { handler.openUri("https://www.stackoverflow.com") } 
) {    
     Text("Open") 
} 
Exocarp answered 16/10, 2022 at 16:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.