Jetpack Compose 中的可滚动时间文本

问题描述 投票:0回答:1

我正在使用 Jetpack Compose 为 Wear OS 制作一个应用程序。我希望 UI 看起来像这样:
enter image description here

这是我现在拥有的代码:

@Composable
fun DefaultPreview() {
    TimeText()
    ScalingLazyColumn(
        Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        item {
            Text(
                text = "Title",
                style = MaterialTheme.typography.title1,
                color = MaterialTheme.colors.primary
            )
        }
        item {
            Text(
                text = "Caption",
                style = MaterialTheme.typography.caption1,
                color = MaterialTheme.colors.primary
            )
        }
        item {
            Column(horizontalAlignment = Alignment.CenterHorizontally) {
                Text(text = "Text content")
                repeat(10) { Text("Line $it") }
            }
        }
    }
}

我遇到的问题是,当我滚动列表时,文本出现在

TimeText
下面,这看起来不太好。
enter image description here

所以我想让

TimeText
与其他文本元素一起滚动。如果我将
TimeText()
作为项目放入
ScalingLazyColumn
中,那么它确实可以工作,但现在
TimeText
下面有一个巨大的空白,这显然是
CurvedLayout

enter image description here

如何摆脱这个空白空间?有没有更好的方法让

TimeText
可以滚动?

android kotlin user-interface android-jetpack-compose
1个回答
0
投票

空白间隙是由

CurvedLayout
创建的
TimeText
产生的,其尺寸等于整个屏幕的大小。在列表之外,这不会成为问题,因为我们的内容只会叠加在
CurvedLayout
之上。但是当我们在列表中使用
TimeText
时,其余列表项会出现在 below
TimeText
,而不是 ontop

我想不出任何方法可以使

TimeText
充当列表项,同时将其他列表项分层在顶部。我也想不出任何方法来切断
TimeText
的空白部分(
Modifier.clip
只改变绘制的内容,它不会改变可组合项的尺寸。

所以我尝试了一种不同的方法,通过为

TimeText
提供垂直偏移,这将与
ScalingLazyColumn
的滚动同步。不幸的是,没有直接的方法可以从
ScalingLazyListState
获取绝对滚动值,因此我不得不诉诸一种 hacky 方法,在
Modifier.onGloballyPositioned
的第一项上使用
ScalingLazyColumn

@Composable
fun DefaultPreview() {
    val scalingLazyListState = rememberScalingLazyListState()

    var initialTimeTextOffset by remember { mutableFloatStateOf(0f) }
    var timeTextOffset by remember { mutableFloatStateOf(0f) }

    TimeText(Modifier.offset(y=timeTextOffset.dp))
    ScalingLazyColumn(
        Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally,
        state = scalingLazyListState
    ) {
        item {
            Text(
                text = "Title",
                style = MaterialTheme.typography.title1,
                color = MaterialTheme.colors.primary,
                modifier = Modifier.onGloballyPositioned {
                    if (scalingLazyListState.centerItemIndex == 1 && scalingLazyListState.centerItemScrollOffset == 0)
                        initialTimeTextOffset = it.positionInRoot().y
                    
                    // for some reason dividing the whole thing by 2 seems to make the animation more 'natural'
                    timeTextOffset = (it.positionInRoot().y - initialTimeTextOffset)/2
                }
            )
        }
        item {
            Text(
                text = "Caption",
                style = MaterialTheme.typography.caption1,
                color = MaterialTheme.colors.primary
            )
        }
        item {
            Column(horizontalAlignment = Alignment.CenterHorizontally) {
                Text(text = "Text content")
                repeat(10) { Text("Line $it") }
            }
        }
    }
}

这种方法对我有用,所以我现在将问题标记为已回答。但我不认为这是“正确”的做法,而且这种方法在性能方面也可能很糟糕。因此,如果有人用更好的方法回答,那么我会将其标记为答案。

© www.soinside.com 2019 - 2024. All rights reserved.