Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @OptIn(ExperimentalPagerApi::class)
- @Composable
- fun HomeScreenToolbarContainer(
- insets: Insets,
- chanTheme: ChanTheme,
- pagerState: PagerState,
- // Each screen has Content() composable and also Toolbar composable. Content() is drawn inside of a
- // HorizontalPager and Toolbar() is draw in this container.
- childScreens: List<ComposeScreenWithToolbar>,
- homeScreenViewModel: HomeScreenViewModel
- ) {
- require(childScreens.isNotEmpty()) { "childScreens is empty!" }
- val currentPage = pagerState.currentPage.coerceIn(0, childScreens.lastIndex)
- val targetPage = pagerState.targetPage.coerceIn(0, childScreens.lastIndex)
- val animationProgress = pagerState.currentPageOffset
- val toolbarHeight = dimensionResource(id = R.dimen.toolbar_height)
- val toolbarTranslationDistancePx = with(LocalDensity.current) { toolbarHeight.toPx() / 3f }
- val toolbarTotalHeight = remember(key1 = insets.topDp) { insets.topDp + toolbarHeight }
- val transitionIsProgress = currentPage != targetPage
- val postListScrollState = homeScreenViewModel.toolbarVisibilityInfo.postListScrollState.collectAsState()
- val touchingTopOrBottomOfList by homeScreenViewModel.toolbarVisibilityInfo.postListTouchingTopOrBottomState.collectAsState()
- val isDraggingPostList by homeScreenViewModel.toolbarVisibilityInfo.postListDragState.collectAsState()
- val isDraggingFastScroller by homeScreenViewModel.toolbarVisibilityInfo.fastScrollerDragState.collectAsState()
- val toolbarAlpha by when {
- isDraggingFastScroller -> animateFloatAsState(targetValue = 0f)
- touchingTopOrBottomOfList -> animateFloatAsState(targetValue = 1f)
- isDraggingPostList -> postListScrollState
- else -> {
- val targetValue = if (postListScrollState.value > 0.5f) 1f else 0f
- animateFloatAsState(targetValue = targetValue)
- }
- }
- Column(
- modifier = Modifier
- .fillMaxWidth()
- .height(toolbarTotalHeight)
- .alpha(toolbarAlpha)
- .background(chanTheme.primaryColorCompose)
- .consumeClicks()
- ) {
- Spacer(modifier = Modifier.height(insets.topDp))
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .height(toolbarHeight)
- ) {
- val zOrders = remember(key1 = childScreens.size) { IntArray(childScreens.size) { 0 } }
- var normalIndex = 0
- for ((pageIndex, _) in childScreens.withIndex()) {
- when (pageIndex) {
- // (Currently animated) Always behind the target and above everything else
- currentPage -> zOrders[pageIndex] = 999
- // (Currently animated) Always at the top
- targetPage -> zOrders[pageIndex] = 1000
- else -> zOrders[pageIndex] = normalIndex++
- }
- }
- for ((pageIndex, currentScreen) in childScreens.withIndex()) {
- val zOrder = zOrders[pageIndex]
- when (pageIndex) {
- currentPage -> {
- val currentToolbarAlpha = lerpFloat(1f, 0f, Math.abs(animationProgress))
- val currentToolbarTranslation = if (animationProgress >= 0f) {
- lerpFloat(0f, toolbarTranslationDistancePx, Math.abs(animationProgress))
- } else {
- lerpFloat(0f, -toolbarTranslationDistancePx, Math.abs(animationProgress))
- }
- BuildChildToolbar(
- composeScreenWithToolbar = currentScreen,
- zOrder = zOrder,
- targetToolbarAlpha = currentToolbarAlpha,
- targetToolbarTranslation = currentToolbarTranslation,
- transitionIsProgress = transitionIsProgress
- )
- }
- targetPage -> {
- val targetToolbarAlpha = lerpFloat(0f, 1f, Math.abs(animationProgress))
- val targetToolbarTranslation = if (animationProgress >= 0f) {
- lerpFloat(-toolbarTranslationDistancePx, 0f, Math.abs(animationProgress))
- } else {
- lerpFloat(toolbarTranslationDistancePx, 0f, Math.abs(animationProgress))
- }
- BuildChildToolbar(
- composeScreenWithToolbar = currentScreen,
- zOrder = zOrder,
- targetToolbarAlpha = targetToolbarAlpha,
- targetToolbarTranslation = targetToolbarTranslation,
- transitionIsProgress = transitionIsProgress
- )
- }
- else -> {
- BuildChildToolbar(
- composeScreenWithToolbar = currentScreen,
- zOrder = zOrder,
- targetToolbarAlpha = 0f,
- targetToolbarTranslation = 0f,
- transitionIsProgress = transitionIsProgress
- )
- }
- }
- }
- }
- }
- }
- @Composable
- private fun BuildChildToolbar(
- composeScreenWithToolbar: ComposeScreenWithToolbar,
- zOrder: Int,
- targetToolbarAlpha: Float,
- targetToolbarTranslation: Float,
- transitionIsProgress: Boolean
- ) {
- key(composeScreenWithToolbar.screenKey) {
- Box(
- modifier = Modifier
- .zIndex(zOrder.toFloat())
- .graphicsLayer {
- alpha = targetToolbarAlpha
- translationY = targetToolbarTranslation
- }
- .consumeClicks(consume = transitionIsProgress)
- ) {
- DisposableEffect(
- key1 = Unit,
- effect = {
- logcat(tag = "BuildChildToolbar") { "Toolbar of screen ${composeScreenWithToolbar.screenKey.key} composed" }
- // Every time the pager is dragged this is called for some unknown reason
- onDispose { logcat(tag = "BuildChildToolbar") { "Toolbar of screen ${composeScreenWithToolbar.screenKey.key} disposed" } }
- }
- )
- composeScreenWithToolbar.Toolbar(this)
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement