我尝试在列表的开始和结尾处显示阴影,以指示列表的左侧/右侧仍有内容。
我希望阴影和整行一样高,因此我使用Modifier.fillMaxHeight()。不幸的是,除非我在调用时指定组件的大小,否则这是不起作用的。
当我像这样调用函数时:
LazyRowWithShadows(modifier = Modifier
.fillMaxWidth(),
contentPadding = PaddingValues(horizontal = 12.dp),
shadowColor = colorResource(R.color.blue_white),
shadowAlphaStart = 0f, shadowAlphaEnd = 0.8f,
shadowWidth = 48.dp
) {
// Content
}阴影不会显示,但其余内容会显示。我必须给修饰符一个height才能使它工作,例如:
LazyRowWithShadows(modifier = Modifier
.fillMaxWidth()
.height(X.dp), // This is what makes it display, but requires knowing the height of the row
contentPadding = PaddingValues(horizontal = 12.dp),
shadowColor = colorResource(R.color.blue_white),
shadowAlphaStart = 0f, shadowAlphaEnd = 0.8f,
shadowWidth = 48.dp
) {
// Content
}我更希望LazyRowWithShadows处理阴影的显示,即使在调用它时没有指定大小。有什么简单的方法可以做到这一点吗?
这是LazyRowWithShadows的代码
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
/** A LazyRow that shows start & end shadows when content is not fully scrolled. */
@ExperimentalAnimationApi
@Composable
fun LazyRowWithShadows(
modifier: Modifier = Modifier,
contentPadding: PaddingValues = PaddingValues(0.dp),
shadowColor: Color = Color.Black,
shadowAlphaStart: Float = 0f,
shadowAlphaEnd: Float = 0.3f,
shadowWidth: Dp = 32.dp,
content: LazyListScope.() -> Unit
) {
val listState = rememberLazyListState()
val showStartShadow by remember {
derivedStateOf {
listState.firstVisibleItemScrollOffset > 0 || listState.firstVisibleItemIndex > 0
}
}
val showEndShadow by remember {
derivedStateOf {
val lastItemIfVisible = listState.layoutInfo.visibleItemsInfo.maxByOrNull { it.index }?.takeIf { it.index == listState.layoutInfo.totalItemsCount - 1 }
if (lastItemIfVisible != null) {
val lastItemEndX = lastItemIfVisible.offset + lastItemIfVisible.size
lastItemEndX > listState.layoutInfo.viewportEndOffset
} else {
true
}
}
}
Box(modifier = modifier) {
LazyRow(
state = listState,
contentPadding = contentPadding,
content = content)
// Start scroll shadow
AnimatedVisibility(visible = showStartShadow, modifier = Modifier.align(Alignment.CenterStart)) {
Box(modifier = Modifier
.fillMaxHeight()
.width(shadowWidth)
.background(brush = Brush.horizontalGradient(colors = listOf(shadowColor.copy(alpha = shadowAlphaEnd), shadowColor.copy(alpha = shadowAlphaStart))))
)
}
// End scroll shadow
AnimatedVisibility(visible = showEndShadow, modifier = Modifier.align(Alignment.CenterEnd)) {
Box(modifier = Modifier
.fillMaxHeight()
.width(shadowWidth)
.background(brush = Brush.horizontalGradient(colors = listOf(shadowColor.copy(alpha = shadowAlphaStart), shadowColor.copy(alpha = shadowAlphaEnd))))
)
}
}
}编辑:我已经尝试了fillMaxSize modifier not working when combined with VerticalScroll in Jetpack Compose中提出的解决方案,但它没有解决我的问题。我尝试用这个答案作为灵感来解决这个问题的改变是:
BoxWithConstraints(modifier = modifier) { // Changed to BoxWithConstraints
LazyRow(
state = listState,
contentPadding = contentPadding,
content = content)
// Start scroll shadow
AnimatedVisibility(visible = showStartShadow, modifier = Modifier.align(Alignment.CenterStart)) {
Box(modifier = Modifier
.height(this@BoxWithConstraints.maxHeight) // Changed from fillMaxHeight
.width(shadowWidth)
.background(brush = Brush.horizontalGradient(colors = listOf(shadowColor.copy(alpha = shadowAlphaEnd), shadowColor.copy(alpha = shadowAlphaStart))))
)
}
// End scroll shadow
AnimatedVisibility(visible = showEndShadow, modifier = Modifier.align(Alignment.CenterEnd)) {
Box(modifier = Modifier
.height(this@BoxWithConstraints.maxHeight) // Changed from fillMaxHeight
.width(shadowWidth)
.background(brush = Brush.horizontalGradient(colors = listOf(shadowColor.copy(alpha = shadowAlphaStart), shadowColor.copy(alpha = shadowAlphaEnd))))
)
}
}我还尝试向AnimatedVisibility元素添加height,但这并没有改变任何事情。
发布于 2021-10-20 14:23:47
在尝试了几种方法之后,使用Modifier.onSizeChanged获取LazyRow的height最终成功了。
将此height转换为dp,并将其传递给影子盒子的Modifier.height。
Box(modifier = modifier) {
val density = LocalDensity.current
var height by remember { mutableStateOf(0) }
val heightDp = remember(height) { with(density){ height.toDp() } }
LazyRow(
modifier = Modifier.onSizeChanged {
height = it.height
},
state = listState,
contentPadding = contentPadding,
content = content)
// Start scroll shadow
AnimatedVisibility(visible = showStartShadow, modifier = Modifier.align(Alignment.CenterStart)) {
Box(modifier = Modifier
.height(heightDp)
.width(shadowWidth)
.background(brush = Brush.horizontalGradient(colors = listOf(shadowColor.copy(alpha = shadowAlphaEnd), shadowColor.copy(alpha = shadowAlphaStart))))
)
}
// End scroll shadow
AnimatedVisibility(visible = showEndShadow, modifier = Modifier.align(Alignment.CenterEnd)) {
Box(modifier = Modifier
.height(heightDp)
.width(shadowWidth)
.background(brush = Brush.horizontalGradient(colors = listOf(shadowColor.copy(alpha = shadowAlphaStart), shadowColor.copy(alpha = shadowAlphaEnd))))
)
}
}https://stackoverflow.com/questions/69646379
复制相似问题