I have 3 Surfaces as can be seen in gif when i click ripple effect propagates without taking the shapes of Surfaces into consideration.
Which are created with
@Composable
fun SurfaceClickPropagationExample() {
// Provides a Context that can be used by Android applications
val context = AmbientContext.current
// 🔥 Offset moves a component in x and y axes which can be either positive or negative
// 🔥🔥 When a component inside surface is offset from original position it gets clipped.
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.clipToBounds()
.clickable(onClick = {})
) {
Surface(
modifier = Modifier
.preferredSize(150.dp)
.padding(12.dp)
.clickable(onClick = {
})
.clipToBounds(),
elevation = 10.dp,
shape = RoundedCornerShape(10.dp),
color = (Color(0xFFFDD835))
) {
Surface(
modifier = Modifier
.preferredSize(80.dp)
.clipToBounds()
.offset(x = 50.dp, y = (-20).dp)
.clickable(onClick = {
}),
elevation = 12.dp,
shape = CircleShape,
color = (Color(0xFF26C6DA))
) {
}
}
Surface(
modifier = Modifier
.preferredSize(110.dp)
.padding(12.dp)
.offset(x = 110.dp, y = 20.dp)
.clickable(onClick = {}),
shape = CutCornerShape(10.dp),
color = (Color(0xFFF4511E)),
elevation = 8.dp
) {}
}
}
I added Modifier.clipToBounds()
to check if it works with it, but it does not work with or without it.
Today, we're releasing version 1.2 of Jetpack Compose, Android's modern, native UI toolkit, continuing to build out our roadmap.
Jetpack Compose is a modern declarative UI Toolkit for Android. Compose makes it easier to write and maintain your app UI by providing a declarative API that allows you to render your app UI without imperatively mutating frontend views.
Jetpack Compose is a modern toolkit for building native Android UI. Jetpack Compose simplifies and accelerates UI development on Android with less code, powerful tools, and intuitive Kotlin APIs. In this tutorial, you'll build a simple UI component with declarative functions.
InteractionSource represents a stream of Interaction s corresponding to events emitted by a component. These Interaction s can be used to change how components appear in different states, such as when a component is pressed or dragged. A common use case is androidx. compose.
Update for compose version 1.0.0-beta08:
Use the new experimental overload of Surface that accepts onClick.
@ExperimentalMaterialApi
@Composable
fun Surface(
onClick: () -> Unit,
modifier: Modifier = Modifier,
shape: Shape = RectangleShape,
color: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(color),
border: BorderStroke? = null,
elevation: Dp = 0.dp,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
indication: Indication? = LocalIndication.current,
enabled: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
content: () -> Unit
): @ExperimentalMaterialApi @Composable Unit
Documentation: https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#Surface(kotlin.Function0,androidx.compose.ui.Modifier,androidx.compose.ui.graphics.Shape,androidx.compose.ui.graphics.Color,androidx.compose.ui.graphics.Color,androidx.compose.foundation.BorderStroke,androidx.compose.ui.unit.Dp,androidx.compose.foundation.interaction.MutableInteractionSource,androidx.compose.foundation.Indication,kotlin.Boolean,kotlin.String,androidx.compose.ui.semantics.Role,kotlin.Function0)
Try applying Modifier.clip(shape: Shape)
before Modifier.clickable
.
When using Modifiers in compose, the order matters. Modifier elements that appear first will be applied first. (documentation)
I was writing this answer when both Surface
and Card
layouts with the onClick
parameter are experimental.
If you don't want to use experimental components, you can try wrapping your view inside a Button
component like this:
Button(
onClick = { /* TODO to handle */ },
shape = /* your shape */,
colors = ButtonDefaults.buttonColors(backgroundColor = /* your color */),
elevation = elevation(defaultElevation = 0.dp, pressedElevation = 0.dp)
) {
/* Here you can paste your parent layout like Box, Column, or Row,
but set max size and horizontal alignment to override the default button's center horizontal alignment */
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.Start
) {
// other stuff there
}
}
Here is the result:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With