15

I am trying to change the button background color on click of that button in Android jetpack compose.

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
SoftwareGuy
  • 1,121
  • 2
  • 11
  • 23

3 Answers3

34

If you want to change the background color only when the Button is pressed you can use the MutableInteractionSource and the collectIsPressedAsState() property.

Something like:

val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()

// Use the state to change the background color
val color = if (isPressed) Color.Blue else Color.Yellow

Column() {
    Button(
        onClick = {},
        interactionSource = interactionSource,
        colors= ButtonDefaults.buttonColors(backgroundColor = color)
    ){
        Text(
         "Button"
        )
    }
}

enter image description here

If you want to achieve a toggle button you can use something like:

var selected by remember { mutableStateOf(false) }
val color = if (selected) Color.Blue else Color.Yellow

Button(
    onClick = { selected = !selected },
    colors= ButtonDefaults.buttonColors(backgroundColor = color)
    ){
        Text("Button")
}

enter image description here

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • A nitpicky problem with this is that it won't change color with really quick clicks if the button is in a scrollable container, because of the fix for this: https://issuetracker.google.com/issues/203141462 – Gak2 Apr 21 '23 at 19:41
  • Its madness there isn't just a simple parameter like `colorOnTouchDown` – J. Doe Jun 27 '23 at 09:04
20

You can do it like this using 1.0.0-alpha11

@Composable
fun ButtonColor() {

    val selected = remember { mutableStateOf(false) }

    Button(colors = ButtonDefaults.buttonColors(
            backgroundColor = if (selected.value) Color.Blue else Color.Gray),

            onClick = { selected.value = !selected.value }) {

    }
}

For a situation where your color changes back when you release your button, try this:

@Composable
fun ButtonColor() {

    val color = remember { mutableStateOf(Color.Blue) }

    Button(
        colors = ButtonDefaults.buttonColors(
            backgroundColor = color.value
        ),

        onClick = {},

        content = {},

        modifier = Modifier.pointerInteropFilter {
            when (it.action) {
                MotionEvent.ACTION_DOWN -> {
                    color.value = Color.Yellow }

                MotionEvent.ACTION_UP  -> {
                    color.value = Color.Blue }
            }
            true
        }
    )
}
Code Poet
  • 6,222
  • 2
  • 29
  • 50
0

In jetpack compose such an effect should implemented by using interactionResource here's a simple example.

@Composable
fun MyButton(){
val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()
val bgcolor = if (isPressed) Color.Red else Color.White
val borderColor = if (isPressed) Color.White else Color.Red

OutlinedButton(
    onClick = {
    }, modifier = Modifier
        .fillMaxWidth()
        .height(40.dp),
    shape = RoundedCornerShape(8.dp),
    border = BorderStroke(1.dp, borderColor),
    interactionSource = interactionSource,
    colors = ButtonDefaults.outlinedButtonColors(backgroundColor = bgcolor)
) {
    Text(text = "button", color=borderColor)
}

}

SalutonMondo
  • 629
  • 9
  • 17