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
)
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'm trying to overlap two Box or perhaps is better to use Row on this case.
My design is one Row overlapped with another one, and I've wrapped it on a Column, is that correct?
This is the design, what I'd like to have is the rectangle of the top be the same size of the one below and then move it some pixels as you can see in the image, but they should have the same width but not the same height.
Is it okay if the hierarchy is :
Column
Box (the one of the top)
Row
Box (the one of the bottom)
Row (inside there is text and it's all the same align)
......
I've faced with this some days ago and I solved it using ConstraintLayout.
What I had to do is :
Add implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-beta02" to build.gradle
Wrap every Box in a ConstraintLayout { .. }
Inside each Box add a Modifier.constrainAs to align the Top Bottom Start End as you want.
If you want the first box be the same width as the second one without hardcoding the dps you should use width = Dimension.fillToConstraints
fillToConstraints - the layout will expand to fill the space defined by its constraints in that dimension.
Basic example without hard-coding :
ConstraintLayout() {
val (title, description) = createRefs()
Box(
modifier = Modifier
.padding(start = 28.dp)
.background(color = Red)
.padding(
horizontal = 16.dp,
)
.constrainAs(title) {
top.linkTo(parent.top)
start.linkTo(parent.start)
end.linkTo(parent.end)
width = Dimension.fillToConstraints
}
) {
Text(text = "Hello World")
}
Box(
modifier = Modifier
.padding(end = 4.dp)
.background(Color.Magenta)
.padding(bottom = 5.dp, start = 8.dp, end = 16.dp, top = 4.dp)
.constrainAs(description) {
top.linkTo(title.top, margin = 16.dp)
start.linkTo(parent.start)
end.linkTo(parent.end)
bottom.linkTo(parent.bottom)
}
) {
Text(text = "Skizo-ozᴉʞS rules")
}
}
Now you have to play with the padding according to your UI and adapt it, result is something like this :
This is way using BoxWithConstraints and not using fixed width and height:
BoxWithConstraints(
Modifier
.background(color = Color.Blue)
.padding(20.dp)) {
val boxWidth = this.maxWidth
Box(
modifier = Modifier
.width(boxWidth - 10.dp)
.background(Color.Red)
) {
Text(text = "Hello Android")
}
Column() {
Spacer(modifier = Modifier
.height(10.dp)
.width(10.dp))
Row( ) {
Spacer(modifier = Modifier.width(10.dp))
Box(
modifier = Modifier
.width(boxWidth)
.zIndex(2f)
.background(Color.Yellow)
) {
Text("aa", modifier = Modifier.background(color = Color.Green))
}
}
}
}
In order for the Composables to overlap, you should put them in the same Box. Try this out:
Box(modifier = Modifier.size(width = 300.dp, height = 100.dp)) {
Row(modifier = Modifier
.size(width = 200.dp, height = 50.dp)
.background(color = Color.Blue)
.align(Alignment.TopEnd)) {}
Row(modifier = Modifier
.size(width = 200.dp, height = 70.dp)
.background(color = Color.Red)
.align(Alignment.BottomStart)) {}
}
You can achieve this in many ways,
#Composable
fun BoxOverBox() {
Box(
modifier = Modifier.fillMaxSize()
.background(Color.White),
contentAlignment = Alignment.Center
) {
Box(
modifier = Modifier
.width(200.dp)
.height(50.dp)
.background(Color.Red)
)
Box(
modifier = Modifier
.width(200.dp)
.height(50.dp)
.zIndex(2f)
.graphicsLayer {
translationX = -50f
translationY = 50f
}
.background(Color.Blue)
)
}
}
I think you must use "matchParentSize" modifier that is avaliabele inside BoxScope, I mean inside Box composable, that modifer measure other children size except itself when it has join the composable at first time to apply the same size to itself.
you can see this modifier in documentation
https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/BoxScope#(androidx.compose.ui.Modifier).matchParentSize()
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..
}
I've created a constraint layout
ConstraintLayout(
Modifier
.fillMaxWidth()
.wrapContentHeight()
) {
Image(
painter = rememberImagePainter(it.photoUrl.toString()),
modifier = Modifier
.constrainAs(photo) {
start.linkTo(parent.start, margin = 30.dp)
top.linkTo(parent.top, margin = 30.dp)
}
.width(130.dp)
)
Column(
modifier = Modifier
.constrainAs(holder) {
start.linkTo(photo.end, margin = 30.dp)
top.linkTo(photo.top)
bottom.linkTo(photo.bottom)
end.linkTo(parent.end, margin = 30.dp)
}
.fillMaxWidth()
.wrapContentHeight(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight(),
text = "Lorem Ipsu auto text ator..."
)
}
As you can see long text can not fit in layout. How Can I wrap text to next line? I tried to change wrapContentWidht() to fillMaxParentWidth but id didn't help.
You can use width = Dimension.fillToConstraints to limit the width to the available space.
within the constrainAs block
In your example:
.constrainAs(holder) {
start.linkTo(photo.end, margin = 30.dp)
top.linkTo(photo.top)
bottom.linkTo(photo.bottom)
end.linkTo(parent.end, margin = 30.dp)
width = Dimension.fillToConstraints
}
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)