如何显示具体的商品数量?

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 个条形,同时保持水平填充。我不知道如何计算。

第二个问题是检测滑动后新条何时比之前的条更高,然后触发操作。我也不知道该怎么做。

我需要为此使用 Layout() 和 Measurables 吗? 在此输入图像描述

Thr*_*ian 5

您可以设置项目宽度

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)