I am facing the issue of border remove from card view in jetpack compose.
Kindly guide me on how to do achieve border removal from card view functionality.
My code is below but not working correctly.
Code
Card(
shape = RoundedCornerShape(0.dp),
border = BorderStroke(0.dp, Transparent),
modifier = Modifier
.height(100.dp)
.padding(start = 10.dp, top = 40.dp, end = 10.dp)
.border(0.dp, Transparent),
) {
Column(
modifier = Modifier
.fillMaxWidth()
.clickable {
submit()
},
) {
Text(
modifier = Modifier
.weight(1f)
.padding(start = 20.dp, top = 20.dp, bottom = 20.dp)
.wrapContentWidth(Alignment.Start),
text = "Submit",
style = typography.h4,
)
}
}
Actually, By default, there is no border in Card. What you are seeing is 1.dp elevation. So if you don't want any elevation make it 0.dp like the following.
Card(
modifier = Modifier
.height(100.dp)
.padding(start = 10.dp, top = 40.dp, end = 10.dp),
elevation = 0.dp
) {
Your content..
}
Related
The dragging part is possible on whole rectangle (Yellow in video) and I want it to be only allowed on the Grey icon
I can drag any part of the yellow part, whether up or down, I want to allow that behavior of dragging only on the Grey part
Left Video is the same as right video, except I made the right's sheetBackgroundColor transparent
#OptIn(ExperimentalMaterialApi::class)
#Composable
fun HomeScreen(modifier: Modifier = Modifier) {
BottomSheetScaffold(
topBar = { AppBar() },
sheetElevation = ZERO_DP,
sheetPeekHeight = BOTTOM_ICON_CONTAINER_SIZE,
sheetBackgroundColor = Color.Transparent,
sheetContent = {
BottomSheetContent(modifier)
}
) {
HomeContent()
}
#Composable
fun BottomSheetContent(
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier
.fillMaxWidth()
.fillMaxHeight(0.8f)
) {
Box(
modifier = modifier
.padding(end = SPACING_QUADRUPLE)
.align(Alignment.End)
.clip(
RoundedCornerShape(
topStart = TRIPLE_CORNER_DP,
topEnd = TRIPLE_CORNER_DP
)
)
.size(BOTTOM_ICON_CONTAINER_SIZE)
.background(MaterialTheme.colors.secondary)
,
contentAlignment = Alignment.BottomCenter
)
{
Icon(
modifier = modifier,
painter = painterResource(id = R.drawable.ic_qr_code),
contentDescription = stringResource(
id = R.string.bottom_sheet_puller
),
tint = Color.Unspecified
)
}
Text(
modifier = modifier
.fillMaxWidth()
.background(MaterialTheme.colors.surface)
.padding(
start = SPACING_DOUBLE,
end = SPACING_DOUBLE,
bottom = SPACING_NORMAL
),
text = "Scan Serial With QR",
style = MaterialTheme.typography.h3,
)
Box(
modifier = modifier
.fillMaxSize()
.background(color = Color.DarkGray)
)
}
}
Wrong Behavior:
Correct Intended Behavior:
I tried replacing a rectangle composables with simple box, but bottom sheet was still considering the full width of the composable
There must be a better solution to intercept a drag gesture and leave all of it within the green box only, but this might suffice.
I made some changes to your BottomSheetContent, intercepting a drag gesture from a Row weighted transparent component and leaving it empty, you can try this one, and the drag gesture is only accepted by the green box,
#Composable
fun BottomSheetContent(
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier
.fillMaxWidth()
.fillMaxHeight(0.8f)
) {
Row {
Box(
modifier = Modifier
.weight(1f)
.draggable(
orientation = Orientation.Vertical,
state = rememberDraggableState {
Toast.makeText(context, "Non Draggable Area", Toast.LENGTH_SHORT).show()
}
).fillMaxWidth().height(150.dp).background(Color.Transparent)) {
}
Box(
modifier = modifier
.padding(end = 8.dp)
.clip(
RoundedCornerShape(
topStart = 12.dp,
topEnd = 12.dp
)
)
.size(150.dp)
.background(MaterialTheme.colors.secondary),
contentAlignment = Alignment.BottomCenter
) {
Icon(
modifier = modifier,
imageVector = Icons.Default.Add,
contentDescription = "",
)
}
}
Text(
modifier = modifier
.fillMaxWidth()
.background(MaterialTheme.colors.surface)
.padding(
start = 8.dp,
end = 8.dp,
bottom = 4.dp
),
text = "Scan Serial With QR",
style = MaterialTheme.typography.h3,
)
Box(
modifier = modifier
.fillMaxSize()
.background(color = Color.DarkGray)
)
}
}
I can't show my pointer click here, but the toast shows when the left area outside of the green box is being dragged.
I was implementing Card shape in Jetpack Compose while I ran into this problem.
What I wanted was to only elevate one end or bottom of the card but I didn't find any relevant documents supporting that.
I tried looking into the implementation code of Card to get an idea (following is the code of the implementation):
#Composable
fun Surface(
modifier: Modifier = Modifier,
shape: Shape = RectangleShape,
color: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(color),
border: BorderStroke? = null,
elevation: Dp = 0.dp,
content: #Composable () -> Unit
) {
Surface(
modifier = modifier,
shape = shape,
color = color,
contentColor = contentColor,
border = border,
elevation = elevation,
content = content,
clickAndSemanticsModifier = Modifier
.semantics(mergeDescendants = false) {}
.pointerInput(Unit) { }
)
}
but here it is accepting elevation in Dp, which means it with elevate the whole Card.
So I don't know how to implement it in Jetpack Compose, can someone help me with the implementation?
Edit:
I created an issue for this question: https://issuetracker.google.com/issues/227767373
You can elevate just the whole bottom like this
#Composable
fun BottomWithShadow(
content: #Composable ColumnScope.() -> Unit
) {
Box {
Card(
shape = RoundedCornerShape(
topEnd = 0.dp,
topStart = 0.dp,
bottomEnd = 0.dp,
bottomStart = 0.dp),
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.align(Alignment.BottomCenter),
elevation = 10.dp
) {}
Column(
modifier = Modifier
.clip(
RoundedCornerShape(
topEnd = 0.dp,
topStart = 0.dp,
bottomEnd = 0.dp,
bottomStart = 0.dp)
)
.background(color = Color.White),
content = content
)
}
}
There is no ripple effect when I click on MyBox() I've added MyTheme(){} to main #Composable screen but it doesn't work. Is something missing?
#Composable
private MyBox(onClickInvoked: () -> Unit) {
MyAppTheme(isSystemInDarkTheme()) {
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.clip(RoundedCornerShape(10.dp))
.background(MaterialTheme.colors.onBackground)
.clickable(onClick = { onClickInvoked.invoke() })
.padding(horizontal = 10.dp, vertical = 15.dp)
) {
Text(
text = "My text",
modifier = Modifier
.align(Alignment.CenterStart)
.padding(end = 95.dp)
.wrapContentWidth()
.wrapContentHeight(),
color = MaterialTheme.colors.primary
)
Image(
painter = painterResource(R.drawable.icon),
modifier = Modifier
.align(Alignment.CenterEnd)
.padding(end = 20.dp)
.size(60.dp)
)
}
}
}
With compose 1.0.5, I see the default indication after set clickable is
LocalIndication.current. And LocalIndication.current is PlatformRipple. Therefore, after you set clickable to your Box, it will have ripple effect.
In your case, I think the ripple effect won't display because your Box background is too dark (normally MaterialTheme.colors.onBackground is black on Light theme)
I think you can change the ripple effect color to make it easy to see.
Surface(
onClick = { onClickInvoked.invoke() },
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(10.dp),
color = MaterialTheme.colors.onBackground, // normally it is black on Light theme
indication = rememberRipple(color = Color.White) // color for your ripple, you can use other suitable MaterialTheme.colors for your case to support Light/Dark mode
) {
Box(modifier = Modifier.padding(horizontal = 10.dp, vertical = 15.dp)) {
// your Box content
...
}
}
There is a Modifier.indication but after testing I see it not working with Modifier.clickable so I use Surface
I don't really know if there is a problem with your theme. I try to pass the material theme, and the ripples will display normally
MaterialTheme() {
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.clip(RoundedCornerShape(10.dp))
.background(MaterialTheme.colors.secondary)
.clickable(onClick = { t = "My text" })
.padding(horizontal = 10.dp, vertical = 15.dp)
) {
Text(
text = t,
modifier = Modifier
.align(Alignment.CenterStart)
.padding(end = 95.dp)
.wrapContentWidth()
.wrapContentHeight(),
color = MaterialTheme.colors.primary
)
Image(
painter = painterResource(R.drawable.ic_launcher_foreground),
modifier = Modifier
.align(Alignment.CenterEnd)
.padding(end = 20.dp)
.size(60.dp),
contentDescription = ""
)
}
}
I need to do something like this:
It's 10 circles views that have same width that depends on parent width.
That I have now:
Column(
modifier = Modifier
.fillMaxWidth()
.background(color = Color.White)
.padding(vertical = 12.dp)
) {
Row(
modifier = Modifier
.padding(horizontal = 20.dp)
.padding(top = 12.dp)
) {
for (i in 1..10) {
Surface(
shape = CircleShape,
modifier = Modifier
.padding(horizontal = 2.dp)
.width(0.dp)
.height(29.dp)
.weight(1F)
.clip(CircleShape),
color = surfaceColor,
onClick = { selected = i },
) {
Text(
modifier = Modifier
.fillMaxWidth()
.wrapContentSize(Alignment.Center),
text = "$i",
color = textColor,
style = subtitle1(),
overflow = TextOverflow.Ellipsis,
)
}
}
}
}
In this case I can set same width of circles by settings Surface weight by 1F, but I need to set height of this circles that depends on width. I'm stuck how to do this.
You can use the aspectRatio modifier.
Apply to the ratio attribute your expected value.
Surface(
shape = CircleShape,
modifier = Modifier
.padding(horizontal = 2.dp)
.width(0.dp)
.weight(1F)
.aspectRatio(1f)
I need the image and text view to be positioned to the start of the card, with the columns children aligned center horizontally, however as you can see from the photo the column is somehow being stretched the width of the screen which is putting the image and text views in the center. Can anyone see any issues with my code on this?
#Composable
fun TrainerCard(profile: TrainerProfile) {
Card(modifier = Modifier
.height(180.dp)
.fillMaxWidth()
.padding(4.dp)) {
Column(modifier = Modifier
.fillMaxHeight()
.width(120.dp)
.border(1.dp, color = Color.Red),
horizontalAlignment = Alignment.CenterHorizontally) {
Image(
modifier = Modifier
.size(120.dp)
.padding(top = 4.dp, start = 4.dp),
painter = painterResource(R.drawable.pokepals_logo),
contentDescription = null
)
Text(
text = profile.trainerName,
style = MaterialTheme.typography.subtitle1)
}
}
}
In your Column add the wrapContentWidth(Alignment.Start) modifier:
Column(modifier = Modifier
.fillMaxHeight()
.width(120.dp)
.wrapContentWidth(Alignment.Start)
.border(1.dp, color = Color.Red),
horizontalAlignment = Alignment.CenterHorizontally
)