animatedFloatAsState содержит значение, отличное от обновленного целевого значения. Составление реактивного ранца
Я пытаюсь анимировать значение с плавающей запятой, используя animateFloatAsState , но пока я обновляю целевое значение, анимированное значение дает мне случайное другое значение.
Например:
Это анимированное значение:
val animatedOffsetValue by animateFloatAsState(
targetValue = titleBarOffsetHeightPx.value
)
Это целевое значение, которое со временем обновляется:
val titleBarOffsetHeightPx = remember { mutableStateOf(0f) }
Поэтому, когда я обновил значение как titleBarOffsetHeightPx.value = "new value" И я проверяю значениеanimatedOffsetValue , оно отличается от titleBarOffsetHeightPx.
полный код:
package com.example.productivitytrackergoalscheduler.features.history.presentation
import android.util.Log
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.example.productivitytrackergoalscheduler.business.util.DateConverter
import com.example.productivitytrackergoalscheduler.business.util.Extensions.isScrolledToTheEnd
import com.example.productivitytrackergoalscheduler.features.core.presentation.navigation.Screen
import com.example.productivitytrackergoalscheduler.features.core.util.SnackbarController
import com.example.productivitytrackergoalscheduler.features.history.presentation.components.DayGoalList
import com.example.productivitytrackergoalscheduler.features.history.presentation.components.HistoryTitleBar
import com.example.productivitytrackergoalscheduler.features.home.presentation.components.CustomNavBar
import com.example.productivitytrackergoalscheduler.features.home.presentation.components.ITEM_WIDTH
import com.example.productivitytrackergoalscheduler.features.home.presentation.util.NavItems
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import kotlin.math.roundToInt
const val NAV_BAR_HEIGHT = ITEM_WIDTH + 110
@Composable
fun HistoryScreen(
...
) {
/** Height of title bar in dp */
val titleBarHeight = 66.dp
/** Height of title bar converted into float for offset */
val titleBarHeightPx = with(LocalDensity.current) { titleBarHeight.roundToPx().toFloat() }
/** Offset value of title bar. How much to move up or down */
val titleBarOffsetHeightPx = remember { mutableStateOf(0f) }
/** Is the scrolling is up or down */
val isUpScrolled = remember { mutableStateOf(false) }
val animatedOffsetValue by animateFloatAsState(
targetValue = titleBarOffsetHeightPx.value
)
val nestedScrollConnection = remember {
object: NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
isUpScrolled.value = available.y < 0
val delta = available.y
val newOffset = titleBarOffsetHeightPx.value + delta
titleBarOffsetHeightPx.value = newOffset.coerceIn(-titleBarHeightPx, 0f)
Log.d("TAG", "onPostFling: animated ${animatedOffsetValue}")
Log.d("TAG", "onPostFling: no animated ${titleBarOffsetHeightPx.value}")
return Offset.Zero
}
override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
val scrolledTo = if(isUpScrolled.value) titleBarHeightPx/3 else titleBarHeightPx/2
if(-titleBarOffsetHeightPx.value < scrolledTo)
{
titleBarOffsetHeightPx.value = 0f
}else{
titleBarOffsetHeightPx.value = -titleBarHeightPx
}
return super.onPostFling(consumed, available)
}
}
}
val endOfScrollList by remember {
derivedStateOf {
scrollState.isScrolledToTheEnd()
}
}
Scaffold(
modifier = Modifier.nestedScroll(nestedScrollConnection),
scaffoldState = scaffoldState,
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(color = MaterialTheme.colors.background)
) {
Box(
modifier = Modifier.fillMaxHeight()
) {
Box(
modifier = Modifier
/** this offset id for while title bar hides or shows
* The lazyColumn content also should move towards the
* up and down as to fill empty space */
.offset { IntOffset(x = 0, y = animatedOffsetValue.roundToInt()) }
.padding(horizontal = 8.dp)
) {
LazyColumn(
state = scrollState,
/** This modifier offset gives the space for title bar */
modifier = Modifier.offset{ IntOffset(x = 0, y = titleBarHeightPx.toInt())}
){
...
}
}
}
/** Title Bar with z-index top */
Box(
modifier = Modifier
.align(Alignment.TopCenter)
.fillMaxWidth()
.offset { IntOffset(x = 0, y = titleBarOffsetHeightPx.value.roundToInt()) }
) {
HistoryTitleBar(navController = navController)
}
/** end title bar*/
...
}
}
}