(Jetpack Compose) Как правильно посчитать значение паралакса?
Я делаю вью с паралакс эффектом и чтоб когда юзер скролит вниз, появлялся actionbar так же как описано в этой статье
https://proandroiddev.com/parallax-in-jetpack-compose-bf521244f49
Делаю это вот так
@Composable
fun HeaderBarParallaxScroll() {
val scrollState = rememberScrollState()
Box {
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(scrollState),
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(500.dp)
.background(Color.White)
.graphicsLayer {
Log.e(
"scroll",
"${scrollState.value.toFloat()}, max = ${scrollState.maxValue}, ratio = ${(scrollState.value.toFloat() / scrollState.maxValue)}"
)
alpha = 1f - ((scrollState.value.toFloat() / scrollState.maxValue) * 1.5f)
translationY = 0.5f * scrollState.value
},
contentAlignment = Alignment.Center
) {
Image(
painterResource(id = R.drawable.ic_launcher_foreground),
contentDescription = "tiger parallax",
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
}
repeat(100) {
Text(
text = "MyText",
modifier = Modifier.background(
Color.White
),
style = TextStyle(
color = Color.Red,
fontSize = 24.sp
)
)
}
}
Box(
modifier = Modifier
.alpha(min(1f, (scrollState.value.toFloat() / scrollState.maxValue) * 5f))
.fillMaxWidth()
.height(60.dp)
.background(Color.Yellow),
contentAlignment = Alignment.CenterStart
) {
Text(
text = "Header bar",
modifier = Modifier.padding(horizontal = 16.dp),
style = TextStyle(
fontSize = 24.sp,
fontWeight = FontWeight.W900,
color = Color.Black
)
)
}
}
}
И вроде бы все работает, но проблема в том, что значения насколько быстро будет уезжать паралакс и насколько быстро будет появляться actionbar зависит от высоты контента.
Как видно в примере вот тут я под изображение добавляю 100 текстов
repeat(100) {
Text(
text = "MyText",
modifier = Modifier.background(
Color.White
),
style = TextStyle(
color = Color.Red,
fontSize = 24.sp
)
)
}
и все работает, но если 100 поменять на 1000, то паралакс медленнее реагирует и что самое главное для того, чтоб появился actionbar нужно пролистать пол списка вниз
Как это сделать, чтоб правильно работало? Нужно, чтоб отклик паралакса и отображение actionbar не зависило от высоты контента, хоть это 100 текстов хоть 1000 должно работать одинаково
Ответы (1 шт):
(scrollState.value.toFloat() / scrollState.maxValue) * 5f высчитывает прозрачность в зависимости от позиции скрола.
Но почему то при этом завязано на общую высоту. Общая высота scrollState.maxValue разная, а потому и результат выражения разный.
А значит чтобы всегда было фиксированное значение нужно зависеть только от scrollState.value, а остальные значения должны быть константами.
Что-то вида scrollState.value.toFloat() / 5000) * 5f
ps: Вместо константы в общем случае правильнее завязываться на высоту картинки, чтобы к моменту ухода картинки была полная непрозрачность, и от него получить нужное число для деления.