Android compose, Indicator size problem with coil - android

Recently, I try to migrate to Jetpack compose.
So, I want to show 'card' where has 'indicator' while loading
but I can't change 'indicator' size in 'SubcomposeAsyncImage'
#Composable
private fun SponsorDialogContent(
imgUrl: String,
) {
Card(
modifier = Modifier
.width(300.dp)
.wrapContentHeight(),
elevation = CardDefaults.cardElevation(0.dp),
shape = RoundedCornerShape(10.dp)
) {
Box() {
SubcomposeAsyncImage(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.heightIn(min = 200.dp),
model = imgUrl,
contentDescription = null,
loading = {
CircularProgressIndicator(modifier = Modifier.size(30.dp).align(Alignment.Center), progress = 1f)
},
alignment = Alignment.Center,
contentScale = ContentScale.FillWidth
)
CircularProgressIndicator(1f, Modifier.width(30.dp).align(Alignment.Center))
}
}
}
So. I have try the code below
#Composable
private fun SponsorDialogContent(
imgUrl: String,
) {
Card(
modifier = Modifier
.width(300.dp)
.wrapContentHeight(),
elevation = CardDefaults.cardElevation(0.dp),
shape = RoundedCornerShape(10.dp)
) {
Box() {
SubcomposeAsyncImage(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.heightIn(min = 200.dp),
model = imgUrl,
contentDescription = null,
loading = {
Box(contentAlignment = Alignment.Center) {
CircularProgressIndicator()
}
},
alignment = Alignment.Center,
contentScale = ContentScale.FillWidth
)
}
}
}
Then, works well, but I don't know why
Does anyone know why?
I tried to find how to work this code but failed

As #Jan Bina mentioned it has propagateMinConstraints = true which means it forces minimum constraints to its direct child only. I explained in this answer how it effects with Surface because Surface is a Box with propagateMinConstraints = true. You can try out these with Box and you will see the same outcomes
Surface(
modifier = Modifier.size(200.dp),
onClick = {}) {
Column(
modifier = Modifier
.size(50.dp)
.background(Color.Red, RoundedCornerShape(6.dp))
) {}
}
Spacer(modifier = Modifier.height(20.dp))
Surface(
modifier = Modifier.size(200.dp),
onClick = {}) {
Column(
modifier = Modifier
.size(50.dp)
.background(Color.Red, RoundedCornerShape(6.dp))
) {
Column(
modifier = Modifier
.size(50.dp)
.background(Color.Green, RoundedCornerShape(6.dp))
) {}
}
}
Spacer(modifier = Modifier.height(20.dp))
Box(
modifier = Modifier.size(200.dp)
) {
Column(
modifier = Modifier
.size(50.dp)
.background(Color.Red, RoundedCornerShape(6.dp))
) {
Column(
modifier = Modifier
.size(50.dp)
.background(Color.Green, RoundedCornerShape(6.dp))
) {}
}
}
In first example on Surface forces Column to have 200.dp size even though it has Modifier.size(50.dp).
In second example Box inside Column has 50.dp size because it's not a direct descendant of Surface.
In third example if we replace Surface(Box with propagateMinConstraints true) with Box it allows direct descendant to use its own constraints or dimensions.
And when you set Modifier.fillMaxWidth you set Constraints as minWidth = parent width, maxWidth = parentWidth
I answered about Constraint types here

If you browse the source code of SubcomposeAsyncImage, you will get to the point where you can see this:
BoxWithConstraints(
modifier = modifier, // this is the modifier you passed to SubcomposeAsyncImage
contentAlignment = alignment,
propagateMinConstraints = true,
) {
// image or your loading content based on state
}
So the behavior you describe is because of your modifier that has heightIn(min = 200.dp) and your progress indicator that ends up being direct child of this Box which has propagateMinConstraints = true.

Related

How to allow drag only on part of the SheetPeek of a BottomContent in BottomSheetScaffold?

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.

How to fillMaxSize() the Box() inside row - Compose

I want to align the button in the BottomEnd of the Box in Row (In the BottonEnd of the bellow Card). I have Card with Row who is devided in two parts - Card and Box, and I want the Box to fill max of the rest of the row. I cannot implement it how I would wanted. Bellow I attached the visualization of the current code.
.
#Composable
fun ProductItem(product: ProductModel, onItemClick: () -> Unit, onAddToCardButton: () -> Unit) {
Card(
modifier = Modifier
.fillMaxSize()
.padding(7.dp)
.clickable { onItemClick() },
shape = MaterialTheme.shapes.large,
elevation = 4.dp
) {
Row(
modifier = Modifier.fillMaxSize()
) {
Card(
modifier = Modifier
.weight(1f),
shape = MaterialTheme.shapes.small,
elevation = 2.dp
) {
Image(
painter = painterResource(id = R.drawable.ic_splash_screen),
contentDescription = "Image of ${product.name}",
)
}
Box(
modifier = Modifier
.weight(2f)
.fillMaxHeight()
.padding(6.dp)
.background(Color.Green)
) {
Column(modifier = Modifier.align(Alignment.TopStart)) {
Text(
text = "${product.number}. ${product.name}",
fontWeight = FontWeight.Bold,
style = MaterialTheme.typography.h4,
)
Text(
text = product.ingredients, fontStyle = FontStyle.Italic
)
}
Button(
modifier = Modifier.align(Alignment.BottomEnd),
onClick = {
onAddToCardButton()
},
shape = RoundedCornerShape(8.dp),
) {
if (product.type == "pizza") {
Text(text = "od ${String.format("%.2f", product.price[0])} zł")
} else {
Text(text = "${String.format("%.2f", product.price[0])} zł")
}
}
}
}
}
}
I expect you display this item in LazyColumn or inside a vertical scrollable.
Modifier.fillMaxHeight doesn't work in this case, because parent height constraint is equal to infinity.
To solve this you ofc can use a static value, but in this case intrinsic measurements can be used to wrap content size.
Add Modifier.height(IntrinsicSize.Max) to your Row.
The code looks good to me at first sight, even tried it and the button is on the bottom right corner. Where do you define the height of your ProductItem card?
Maybe you can try to define it in the code you provided by changing the
.fillMaxSize()
modifier to
.fillMaxWidth()
.requiredHeight(**.dp)
at your first Card composable.
So it would look something like this:
#Composable
fun ProductItem(product: ProductModel, onItemClick: () -> Unit, onAddToCardButton: () -> Unit) {
Card(
modifier = Modifier
.fillMaxWidth()
.requiredHeight(**.dp)
.padding(7.dp)
.clickable { onItemClick() },
shape = MaterialTheme.shapes.large,
elevation = 4.dp
) {
...
}
As Phil Dukhov answered Modifier.height(IntrinsicSize.Max) works for me.
Just set the modifier to the Root element in your Row. In your case it's Card (change .fillMaxWidth() to .height(IntrinsicSize.Max)):
Card(
modifier = Modifier
.height(IntrinsicSize.Max)
.padding(7.dp)
.clickable { onItemClick() },
shape = MaterialTheme.shapes.large,
elevation = 4.dp
)

How to optimise laggy JetPack Compose layout

I'm using a HorizontalPager from accompanist package. The pager will have 1 page for each exercise stored by the user.
Each page in the pager has a LazyColumn which contain multiple cards with controls such as IconButtons and BasicTextField. The number of cards depends on number of sets configured by the user. I expect the typical number to be between 1 to 8 but only 3 to 5 would be visible on the screen at any given time (depending on the screen size and resolution).
The issue is that when this layout produces noticeable lag (animations skip frames) every time the HorizontalPager needs to build a new page that has more than 3 cards. This happens when swapping between pages. The same happens in debug and release versions running on a real device (Galaxy S10e) and emulator.
I'm trying to optimise this layout, so each frame renders in no more than 16ms regardless of the number of cards shown on the screen.
I've previously tried to solve this issue by setting fixed heights to some composables but that didn't help much. I've also tried using Text instead of BasicTextField, which would be then replaced with BasicTextField when users taps on the text but this hasn't helped much, therefore I removed this implementation.
Do you have some suggestions how performance of this layout could be improved to eliminate the lag?
Below is my code, screen shoot of the app screen and profiler:
#ExperimentalPagerApi
#Composable
fun WorkoutSessionScreen(
navHostController: NavHostController,
) {
val pagerState = rememberPagerState()
Scaffold(
topBar = { MyTopAppBar(navHostController = navHostController) }
) {
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.background(MaterialTheme.colors.background)
.imePadding()
) {
HorizontalPager(
count = 10, state =
pagerState,
itemSpacing = 16.dp
) {
Log.e("==>", "Building horizontal pager")
TrackingControls()
}
Box(
modifier = Modifier
.height(70.dp)
.fillMaxWidth()
.background(Color(0xFAF7F7FF))
.align(Alignment.BottomCenter)
) {
Column(
Modifier.fillMaxWidth()
) {
Divider(color = Color(0x2A5C5C5C))
BottomControls()
}
}
}
}
}
#Composable
private fun TrackingControls() {
LazyColumn(
Modifier
.fillMaxHeight()
.fillMaxWidth(),
contentPadding = PaddingValues(vertical = 8.dp)
) {
items(6) { item ->
SetsAndRepsTrackingControls(
modifier = Modifier
)
}
}
}
#Composable
private fun BottomControls() {
Text(text = "Bottom Controlls")
}
#Composable
fun SetsAndRepsTrackingControls(modifier: Modifier = Modifier) {
val add = painterResource(id = R.drawable.ic_round_add_24)
val remove = painterResource(id = R.drawable.ic_round_remove_24)
Card(
modifier
.fillMaxWidth()
.height(200.dp)
.padding(vertical = 16.dp, horizontal = 8.dp),
backgroundColor = MaterialTheme.colors.surface,
shape = RoundedCornerShape(12.dp),
) {
Column() {
ControlsHeader()
TrackingInput(label = "REPS", add, remove)
Divider(color = Color.LightGray)
TrackingInput(label = "WEIGHT (KG)", add, remove)
}
}
}
#Composable
private fun ControlsHeader() {
Row(
modifier = Modifier
.height(56.dp)
.fillMaxWidth()
.background(MaterialTheme.colors.primary, RoundedCornerShape(12.dp))
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(text = "Set 1")
Text(text = "CheckBox")
}
}
#Composable
private fun TrackingInput(label: String = "Preview", add: Painter, remove: Painter) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(60.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
IconButton(onClick = {}) {
Icon(
painter = painterResource(id = R.drawable.ic_round_remove_24),
contentDescription = "Minus",
tint = MaterialTheme.colors.onSurface
)
}
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
BasicTextField(
singleLine = true,
value = "8",
onValueChange = {},
textStyle = TextStyle(
textAlign = TextAlign.Center,
color = MaterialTheme.colors.onSurface
),
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = label,
style = MaterialTheme.typography.overline.copy(color = MaterialTheme.colors.onSurface)
)
}
IconButton(onClick = { Log.d("==>", "tada") }) {
Icon(
painter = painterResource(id = R.drawable.ic_round_add_24),
contentDescription = "Minus",
tint = MaterialTheme.colors.onSurface
)
}
}
}
This profiler print screen shows rendering of a single card called SetsAndRepsTrackingControls

Arrange a single item inside a LazyColumn by using weight modifier

I am looking to have a result like this. Two block with 2/3 size and 1/3 size respectively.
I am getting the expected result with this code.
#Preview(showBackground = true)
#Composable
fun LayoutCheck() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Surface(
modifier = Modifier
.width(200.dp)
.weight(3f),
color = MaterialTheme.colors.primary
) {}
Surface(
modifier = Modifier
.width(200.dp)
.weight(1f),
color = MaterialTheme.colors.secondary
) {}
}
}
But when i put that inside a lazycolumn, nothing seems working. Not even getting a display.
#Preview(showBackground = true)
#Composable
fun LayoutCheck() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(20.dp)
) {
item {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Surface(
modifier = Modifier
.width(200.dp)
.weight(3f),
color = MaterialTheme.colors.primary
) {}
Surface(
modifier = Modifier
.width(200.dp)
.weight(1f),
color = MaterialTheme.colors.secondary
) {}
}
}
}
}
}
If i remove t he weight and put some height,it works. But i don't want to hardcode there. So how to make it work with weight. Expecting some help..
Thanks
NB: I want scroll functionality, that's why going with LazyColumn
Real World scenario :
A Login Screen, with Logo at the first 2/3 portion and a Text and Button at the bottom 1/3 portion
Scenario 1 : Working Perfectly:
Scenario 2: If users font is bigger or screen is rotated, they wont be able to see the button
Since you have only one item just use a Column with a verticalScroll:
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.verticalScroll(scrollState),
horizontalAlignment = Alignment.CenterHorizontally,
) {
//...
}
Also if you want 2/3 and 1/3, use in the 1st Surface the weight(2f) modififer.
You prevent the text from being resized by applying the weight modifier. Instead, I suggest that you make the element spacing flexible, like this:
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(Modifier.weight(1f))
Image(
painter = painterResource(id = R.drawable.my_image),
contentDescription = "",
)
Spacer(Modifier.weight(1.35f))
Text(
"Your app is being reviewed",
)
Spacer(Modifier.weight(0.2f))
Button(onClick = { /*TODO*/ }) {
Text("Log out")
}
Spacer(Modifier.weight(0.2f))
}
Spacers explanation:

How to achieve this layout in Jetpack Compose

I'm trying to use the new Jetpack Compose UI framework, but I'm running into an issue. I'd like to achieve this layout, which in xml is pretty easy to achieve:
But I can't figure out how to make the vertical divider take up the available vertical space, without specifying a fixed height. This code that I've tried doesn't seem to work:
#Composable
fun ListItem(item: PlateUI.Plate) {
Surface(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(8.dp),
elevation = 2.dp
) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier
.padding(8.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Code")
Text(text = item.code)
}
Spacer(
modifier = Modifier
.preferredWidth(1.dp)
.background(color = MaterialTheme.colors.onSurface.copy(0.12f))
)
Spacer(modifier = Modifier.weight(1f))
Text(
modifier = Modifier
.padding(horizontal = 8.dp, vertical = 34.dp),
text = item.name
)
Spacer(modifier = Modifier.weight(1f))
}
}
}
I keep getting this result:
I also tried with ConstraintLayout, but it still didn't work
#Composable
fun ListItem(item: PlateUI.Plate) {
Surface(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(8.dp),
elevation = 2.dp
) {
ConstraintLayout(
modifier = Modifier.fillMaxWidth(),
) {
val(column, divider, text) = createRefs()
Column(
modifier = Modifier
.padding(8.dp)
.constrainAs(column){
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
},
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Code")
Text(text = item.code)
}
Spacer(
modifier = Modifier
.preferredWidth(1.dp)
.background(color = MaterialTheme.colors.onSurface.copy(0.12f))
.constrainAs(divider){
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
start.linkTo(column.end)
}
)
Text(
modifier = Modifier
.padding(horizontal = 8.dp, vertical = 34.dp)
.constrainAs(text){
start.linkTo(divider.end)
end.linkTo(parent.end)
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
},
text = item.name
)
}
}
}
But nothing seems to work. Is this a bug, a missing feature or am I just missing something?
EDIT: Apparently the real problem is that the divider doesn't know how to measure when the Surface doesn't have a fixed height, setting height equal to some number solves the issue, but then the view doesn't adapt to the content height anymore, so this can't be the solution
You can apply:
the modifier .height(IntrinsicSize.Max) to the Row
the modifiers .width(1.dp).fillMaxHeight() to the Spacer
You can read more about the Intrinsic measurements here.
Something like:
Row(
modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Max),
verticalAlignment = Alignment.CenterVertically
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
....
) {
Text(text = "....")
}
Spacer(
modifier = Modifier
.width(1.dp)
.fillMaxHeight()
.background(color = MaterialTheme.colors.onSurface.copy(0.12f))
)
Text(...)
}
You can set Intrinsic.Max for the preferredHeight of the Row, then set the Spacer to fill max height. You can read more on Intrinsics in this codelab section.
#Composable
fun ListItem() {
Surface(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(8.dp),
elevation = 2.dp
) {
Row(
modifier = Modifier.fillMaxWidth().preferredHeight(IntrinsicSize.Max),
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier
.padding(8.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Code")
Text(text = "2456")
}
Spacer(
modifier = Modifier
.preferredWidth(1.dp)
.fillMaxHeight()
.background(color = Color.Black.copy(0.12f))
)
Spacer(modifier = Modifier.weight(1f))
Text(
modifier = Modifier
.padding(horizontal = 8.dp, vertical = 34.dp),
text = "Some name"
)
Spacer(modifier = Modifier.weight(1f))
}
}
}
I've solved it using constraint layout:
Box(modifier = Modifier.padding(Dp(50f))) {
ConstraintLayout(
modifier = Modifier
.border(width = Dp(1f), color = Color.Black)
.fillMaxWidth()
) {
val (left, divider, right) = createRefs()
Column(
modifier = Modifier
.padding(horizontal = Dp(20f))
.constrainAs(left) {
width = Dimension.wrapContent
start.linkTo(parent.start)
top.linkTo(parent.top)
end.linkTo(divider.start)
bottom.linkTo(parent.bottom)
}
) {
Text(text = "Code")
Text(text = "A12")
}
Box(
modifier = Modifier
.width(Dp(1f))
.background(Color.Black)
.constrainAs(divider) {
width = Dimension.wrapContent
height = Dimension.fillToConstraints
start.linkTo(left.end)
top.linkTo(parent.top)
end.linkTo(right.start)
bottom.linkTo(parent.bottom)
}
)
Box(
modifier = Modifier
.constrainAs(right) {
width = Dimension.fillToConstraints
start.linkTo(divider.end)
top.linkTo(parent.top)
end.linkTo(parent.end)
bottom.linkTo(parent.bottom)
}
) {
Text(
text = "Test",
modifier = Modifier
.padding(vertical = Dp(100f))
.align(Alignment.Center)
)
}
}
}
The key part is using that modifier height = Dimension.fillToConstraints
There are plenty of solutions here, but I thought I could demonstrate the ConstraintLayout approach and add a helpful usage of the IntrinsicSize enum that solves one of the issues (needing an adaptive height for the composable). Interestingly, either IntrinsicSize.Max or IntrinsicSize.Min will yield the desired behavior.
I used most of your code. The key differences are:
declares a guideline (my value passed in for the fraction does not produce the exact result you were looking for, but can be adjusted easily (use a fraction slightly smaller than .2) This can be useful if you expect wrapContent to alter your left Text to vary the location of a spacer, but would prefer a consistent spacer location across a list of these items.
others have mentioned, spacer modifier should include .fillMaxHeight()
define the height of the surface wrapper to be .height(IntrinsicSize.Min) docs ref here: https://developer.android.com/jetpack/compose/layout#intrinsic-measurements
divider start is constrained to the guideline
had to change the Spacer modifier to access the width, instead of preferredWidth
#Composable
fun ListItem(item: Plate) {
Surface(
modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Min),
shape = RoundedCornerShape(8.dp),
elevation = 2.dp
) {
ConstraintLayout(
modifier = Modifier.fillMaxWidth(),
) {
val guideline = createGuidelineFromStart(0.2f)
val(column, divider, text) = createRefs()
Column(
modifier = Modifier
.padding(8.dp)
.constrainAs(column){
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
end.linkTo(guideline)
},
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Code")
Text(text = item.code)
}
Spacer(
modifier = Modifier
.constrainAs(divider){
top.linkTo(column.top)
bottom.linkTo(column.bottom)
start.linkTo(guideline)
}
.width(1.dp)
.fillMaxHeight()
.background(color = MaterialTheme.colors.onSurface.copy(0.12f))
)
Text(
modifier = Modifier
.padding(horizontal = 8.dp, vertical = 34.dp)
.constrainAs(text){
start.linkTo(divider.end)
end.linkTo(parent.end)
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
},
text = item.name
)
}
}
}
I think Row layout is enough.
#Preview(showBackground = true, heightDp = 100)
#Composable
fun ListItem(item: PlateUI.Plate = PlateUI.Plate()) {
Card(
shape = RoundedCornerShape(8.dp)
) {
Row(
modifier = Modifier
.fillMaxSize(),
verticalAlignment = Alignment.CenterVertically
) {
Text(
modifier = Modifier.padding(8.dp),
text = "Code\n${item.code}",
textAlign = TextAlign.Center
)
Box(
Modifier
.fillMaxHeight()
.width(1.dp)
.background(color = MaterialTheme.colors.onSurface.copy(0.12f))
)
Text(
modifier = Modifier
.weight(1f)
.padding(8.dp),
text = item.name,
textAlign = TextAlign.Center
)
}
}
}

Categories

Resources