Reputation: 67413
As can be seen in gif
when Column
that contains of Text, Spacer, and LazyRowForIndexed
is touched ripple is not propagating with circular motion. And it gets touched effect even when horizontal list is touched.
@Composable
fun Chip(modifier: Modifier = Modifier, text: String) {
Card(
modifier = modifier,
border = BorderStroke(color = Color.Black, width = Dp.Hairline),
shape = RoundedCornerShape(8.dp)
) {
Row(
modifier = Modifier.padding(start = 8.dp, top = 4.dp, end = 8.dp, bottom = 4.dp),
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier.preferredSize(16.dp, 16.dp)
.background(color = MaterialTheme.colors.secondary)
)
Spacer(Modifier.preferredWidth(4.dp))
Text(text = text)
}
}
}
@Composable
fun TutorialSectionCard(model: TutorialSectionModel) {
Column(
modifier = Modifier
.padding(top = 8.dp)
.clickable(onClick = { /* Ignoring onClick */ })
.padding(16.dp)
) {
Text(text = model.title, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.h6)
Spacer(Modifier.preferredHeight(8.dp))
Providers(AmbientContentAlpha provides ContentAlpha.medium) {
Text(model.description, style = MaterialTheme.typography.body2)
}
Spacer(Modifier.preferredHeight(16.dp))
LazyRowForIndexed(items = model.tags) { _: Int, item: String ->
Chip(text = item)
Spacer(Modifier.preferredWidth(4.dp))
}
}
}
@Preview
@Composable
fun TutorialSectionCardPreview() {
val model = TutorialSectionModel(
clazz = MainActivity::class.java,
title = "1-1 Column/Row Basics",
description = "Create Rows and Columns that adds elements in vertical order",
tags = listOf("Jetpack", "Compose", "Rows", "Columns", "Layouts", "Text", "Modifier")
)
Column {
TutorialSectionCard(model)
TutorialSectionCard(model)
TutorialSectionCard(model)
}
}
What should be done to have circular effect, but not when list itself or an item from list is touched, or scrolled?
Upvotes: 24
Views: 34511
Reputation: 3858
Apparently rememberRipple() has been deprecated and we have to use new provided APIs.
rememberRipple() -> ripple()
Modifier.clickable(
onClick = {},
interactionSource = remember { MutableInteractionSource() },
indication = ripple()
)
More info in the official docs: https://developer.android.com/jetpack/compose/touch-input/user-interactions/migrate-indication-ripple#migrate-remember-ripple
Edit: Please someone correct me if I am wrong, but at the time of this writing, this is only available in androidx.compose.material3:material3:1.3.0-alpha01
BUT has not yet been released... So we have a deprecated method that throws error when you compile, and the solution has not been released yet.
Upvotes: 6
Reputation: 854
To apply the circular effect globally you can provide the unbounded ripple indication to all components in the tree:
val ripple = rememberRipple(bounded = false) // Applies circular ripple animation effect
CompositionLocalProvider(
LocalIndication provides ripple
) {
MaterialTheme(
colors = ...,
typography = ...,
shapes = ...,
content = content
)
}
Upvotes: 0
Reputation: 97
same as @jns just added an extra line
modifier = modifier
.clickable (
interactionSource = remember { MutableInteractionSource() }, // without this indication parameter gets an error
indication = rememberRipple(
bounded = true
),
onClick = {
//on click
}
)
Upvotes: 1
Reputation: 1674
I'm using this approach:
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(
color = Color.Black
),
onClick = {
}
)
Upvotes: 11
Reputation: 67413
I also figured out how to keep ripple only for the card not the scrollable list that contains tags. To prevent ripple only move through cards use a Box
which places it's children as a stack, and add clickable to section that contains header and text.
@Composable
fun TutorialSectionCard(
model: TutorialSectionModel,
onClick: ((TutorialSectionModel) -> Unit)? = null
) {
Card(
modifier = Modifier.padding(vertical = 3.dp, horizontal = 8.dp),
elevation = 1.dp,
shape = RoundedCornerShape(8.dp)
) {
Box(
contentAlignment = Alignment.BottomStart
) {
TutorialContentComponent(onClick, model)
TutorialTagsComponent(model)
}
}
}
@Composable
private fun TutorialContentComponent(
onClick: ((TutorialSectionModel) -> Unit)?,
model: TutorialSectionModel
) {
Column(Modifier
.clickable(
onClick = { onClick?.invoke(model) }
)
.padding(16.dp)
) {
Text(
text = model.title,
fontWeight = FontWeight.Bold,
style = MaterialTheme.typography.h6
)
// Vertical spacing
Spacer(Modifier.height(8.dp))
// Description text
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Text(model.description, style = MaterialTheme.typography.body2)
}
// Vertical spacing
Spacer(Modifier.height(36.dp))
}
}
@Composable
private fun TutorialTagsComponent(model: TutorialSectionModel) {
Column(Modifier.padding(12.dp)) {
// Horizontal list for tags
LazyRow(content = {
items(model.tags) { tag ->
TutorialChip(text = tag)
Spacer(Modifier.width(8.dp))
}
})
}
}
Upvotes: 1
Reputation: 6952
You have to apply a Theme to your composable, which in turn provides a default ripple factory, or you have to set the ripple explicitly:
@Preview
@Composable
fun TutorialSectionCardPreview() {
MaterialTheme() {
Column {
TutorialSectionCard
...
}
}
}
or
Column(
modifier = Modifier
.padding(top = 8.dp)
.clickable(
onClick = { /* Ignoring onClick */ },
indication = rememberRipple(bounded = true)
)
.padding(16.dp)
) {
// content
}
(As of compose version 1.0.0-alpha09 there seems to be no way to prevent the ripple from showing when content is scrolled)
Upvotes: 40