@Composable
fun PreviewLayout() {
fun getRandomString(length: Int): String {
val allowedChars = ('A'..'Z') ('a'..'z') ('0'..'9')
return (1..length)
.map { allowedChars.random() }
.joinToString("")
}
val horizontalScrollState = rememberScrollState()
LazyColumn(
modifier = Modifier
.background(Color.Blue)
.fillMaxHeight()
.wrapContentWidth()
.horizontalScroll(horizontalScrollState)
) {
items(5) { index ->
Text(
text = getRandomString((index 1) * 4).uppercase(),
color = Color.Black,
fontSize = 16.sp,
modifier = Modifier
.padding(8.dp)
.background(Color.Yellow)
)
}
}
}
Preview of the layout:
I'd like to have the items width be the same as the largest item in the list.
Notice the .horizontalScroll(horizontalScrollState)
, this is to allow horizontal scrolling.
What I'd like:
I need to use a LazyColumn
but if I could use a Column
I'd write it this way:
Column(
modifier = Modifier
.background(Color.Blue)
.horizontalScroll(horizontalScrollState)
.fillMaxHeight()
.width(IntrinsicSize.Min)
) {
repeat(5) { index ->
Text(
text = getRandomString((index 1) * 4).uppercase(),
color = Color.Black,
fontSize = 16.sp,
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
.background(Color.Yellow)
)
}
}
CodePudding user response:
This is not possible when horizontal srolling is enabled.
Regular Modifier.fillMaxWidth can't work inside the scrolling horizontally layouts as the items are measured with Constraints.Infinity as the constraints for the main axis.
If you want your Column solution to work, you need to place it inside another contain (like a Box) and apply horizontal scrolling to the parent. Scrolling on the Column itself needs to be removed:
Box(
modifier = Modifier
.requiredWidth(250.dp)
.fillMaxHeight()
.horizontalScroll(rememberScrollState())
) {
Column(
modifier = Modifier
.background(Color.Blue)
.fillMaxHeight()
.width(IntrinsicSize.Min)
) {
repeat(5) { index ->
Text(
text = getRandomString((index 1) * 40).uppercase(),
color = Color.Black,
fontSize = 16.sp,
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
.background(Color.Yellow)
)
}
}
}
CodePudding user response:
You need to calculate width of the widest element separately. You can do it by placing an invisible copy of you cell with widest content in a
Box
along withLazyColumn
.In your sample it's easy - just get the longest string. If in the real project you can't decide which of contents is gonna be the widest one, you have two options:
1.1. Place all of them one on top of each other. You can do it only if you have some limited number of cells,
1.2. Otherwise you have to made some approximation and filter a short list of the ones you expect to be the widest ones.
Because of
horizontalScroll
maxWidth
constraint is infinity, you have to pass calculated width manually. You can get it withonSizeChanged
:
@Composable
fun TestScreen(
) {
fun getRandomString(length: Int): String {
val allowedChars = ('A'..'Z') ('a'..'z') ('0'..'9')
return (1..length)
.map { allowedChars.random() }
.joinToString("")
}
val items = remember {
List(30) { index ->
getRandomString((index 1) * 4).uppercase()
}
}
val maxLengthItem = remember(items) {
items.maxByOrNull { it.length }
}
val (maxLengthItemWidthDp, setMaxLengthItemWidthDp) = remember {
mutableStateOf<Dp?>(null)
}
val horizontalScrollState = rememberScrollState()
Box(
Modifier
.background(Color.Blue)
.horizontalScroll(horizontalScrollState)
) {
LazyColumn(
Modifier.fillMaxWidth()
) {
items(items) { item ->
Cell(
item,
modifier = if (maxLengthItemWidthDp != null) {
Modifier.width(maxLengthItemWidthDp)
} else {
Modifier
}
)
}
}
if (maxLengthItem != null) {
val density = LocalDensity.current
Cell(
maxLengthItem,
modifier = Modifier
.requiredWidthIn(max = Dp.Infinity)
.onSizeChanged {
setMaxLengthItemWidthDp(with(density) { it.width.toDp() })
}
.alpha(0f)
)
}
}
}
@Composable
fun Cell(
item: String,
modifier: Modifier,
) {
Text(
text = item,
color = Color.Black,
fontSize = 16.sp,
modifier = modifier
.padding(8.dp)
.background(Color.Yellow)
)
}
Result:
CodePudding user response:
@Composable
fun PreviewLayout() {
fun getRandomString(length: Int): String {
val allowedChars = ('A'..'Z') ('a'..'z') ('0'..'9')
return (1..length)
.map { allowedChars.random() }
.joinToString("")
}
val horizontalScrollState = rememberScrollState()
LazyColumn(
modifier = Modifier
.background(Color.Blue)
.fillMaxHeight()
.horizontalScroll(horizontalScrollState)
) {
items(5) { index ->
Text(
text = getRandomString((index 1) * 4).uppercase(),
color = Color.Black,
fontSize = 16.sp,
modifier = Modifier
.padding(8.dp)
.width(width = 200.dp)
.background(Color.Yellow)
)
}
}
}