Waf*_*_ck 2 android kotlin android-jetpack android-jetpack-compose
我想创建一个带有可以左右滚动(从右侧开始)的图表的视图。我已经使用 LazyRow 完成了此操作并将reverseLayout 设置为true。
val scrollState = rememberLazyListState(0)
LazyRow(
reverseLayout = true,
state = scrollState
) {
items(charts) {data ->
ChartBar()
}
}
Run Code Online (Sandbox Code Playgroud)
我的图表是可交换的并且显示正确。
我的问题是我需要始终在屏幕宽度上显示 7 个条形,同时保持水平填充。我不知道如何计算。
第二个问题是检测滑动后新条何时比之前的条更高,然后触发操作。我也不知道该怎么做。
您可以设置项目宽度
val padding = 12.dp
val itemCount = 7
val screenWidthDp = LocalConfiguration.current.screenWidthDp
val itemWidth = (screenWidthDp - (itemCount + 1) * padding.value) / itemCount
Run Code Online (Sandbox Code Playgroud)
或者您可以使用 LazyRow 包装BoxWithConstraints并获取 maxWidh 参数,而不是LocalConfiguration.current.screenWidthDp使用相同的方式应用。
要获得最高的项目,您需要提供有关 ChartBar 的构造方式的更多信息。如果它们是不同高度的物品,您可以按如下方式进行。
@Preview
@Composable
private fun ChartTest() {
val charts = remember {
List(50) {
Random.nextInt(40, 500)
}
}
val padding = 12.dp
val itemCount = 7
val scrollState = rememberLazyListState(0)
scrollState.layoutInfo.visibleItemsInfo
var tallestItem by remember {
mutableStateOf(0)
}
var currentMaxHeight by remember {
mutableStateOf(0)
}
val context = LocalContext.current
LaunchedEffect(tallestItem) {
if (tallestItem > currentMaxHeight) {
currentMaxHeight = tallestItem
Toast.makeText(context, "Tallest item $tallestItem", Toast.LENGTH_SHORT).show()
}
}
val screenWidthDp = LocalConfiguration.current.screenWidthDp
val itemWidth = (screenWidthDp - (itemCount + 1) * padding.value) / itemCount
LazyRow(
contentPadding = PaddingValues(horizontal = padding),
modifier = Modifier.fillMaxWidth()
.border(2.dp, Color.Red)
.onPlaced {
val newHeight = it.size.height
if (newHeight > tallestItem) {
tallestItem = newHeight
}
if (currentMaxHeight == 0) {
currentMaxHeight = newHeight
}
},
reverseLayout = true,
horizontalArrangement = Arrangement.spacedBy(padding),
state = scrollState
) {
itemsIndexed(charts) { index, data ->
ChartBar(
modifier = Modifier.width(itemWidth.dp).height(charts[index].dp)
)
}
}
}
@Composable
private fun ChartBar(
modifier: Modifier
) {
Box(modifier.background(Color.Green, RoundedCornerShape(16.dp)))
}
Run Code Online (Sandbox Code Playgroud)
如果它们包含数据,您可以使用它们有多高
scrollState.layoutInfo.visibleItemsInfo
这可以这样做
@Preview
@Composable
private fun ChartTest2() {
BoxWithConstraints(
modifier = Modifier.height(400.dp)
) {
val context = LocalContext.current
val density = LocalDensity.current
val charts = remember {
List(50) {
Random.nextInt(40, 400)
}
}
val padding = 24.dp
val itemCount = 7
val itemWidth = (maxWidth.value - (itemCount + 1) * padding.value) / itemCount
val scrollState = rememberLazyListState(0)
var currentMaxHeight by remember {
mutableStateOf(0)
}
val tallestItem by remember {
derivedStateOf {
val visibleItemsInfo = scrollState.layoutInfo.visibleItemsInfo
var maxHeight = 0
if (visibleItemsInfo.isNotEmpty()) {
visibleItemsInfo.forEach {
val index = it.index
maxHeight = charts[index].coerceAtLeast(maxHeight)
}
}
if (currentMaxHeight == 0) {
currentMaxHeight = (maxHeight * density.density).toInt()
}
(maxHeight * density.density).toInt()
}
}
LaunchedEffect(tallestItem) {
if (tallestItem > currentMaxHeight) {
currentMaxHeight = tallestItem
Toast.makeText(context, "Tallest item $tallestItem", Toast.LENGTH_SHORT).show()
}
}
LazyRow(
contentPadding = PaddingValues(horizontal = padding),
modifier = Modifier.fillMaxSize()
.border(2.dp, Color.Red),
reverseLayout = true,
horizontalArrangement = Arrangement.spacedBy(padding),
state = scrollState
) {
itemsIndexed(charts) { index, data ->
ChartBar(
modifier = Modifier.width(itemWidth.dp).fillMaxHeight(),
barHeight = charts[index].dp
)
}
}
}
}
@Composable
private fun ChartBar(
modifier: Modifier,
barHeight: Dp
) {
Column(modifier) {
Spacer(modifier = Modifier.weight(1f))
Box(
Modifier.fillMaxWidth().height(barHeight)
.background(Color.Green, RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp))
)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |