Skip to content

Commit

Permalink
WTA #71: Added accompanist for horizontal pager and modifier of mater…
Browse files Browse the repository at this point in the history
…ial 3 version.
  • Loading branch information
Jacob3075 committed May 13, 2023
1 parent 92813f5 commit 59dc842
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
2 changes: 2 additions & 0 deletions details/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ android {
}

dependencies {
implementation("com.google.accompanist:accompanist-pager:0.29.0-alpha")
implementation("com.google.accompanist:accompanist-pager-indicators:0.29.0-alpha")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.jacob.wakatimeapp.details.ui.modiffiers

import androidx.compose.material3.TabPosition
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.layout
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.lerp
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.PagerState

/**
* [See Issue](https://github.com/google/accompanist/issues/1076)
* [Source](https://github.com/c5inco/Material3Pager/blob/main/app/src/main/java/com/c5inco/material3pager/PagerTab.kt)
*/
@ExperimentalPagerApi
fun Modifier.pagerTabIndicatorOffset(
pagerState: PagerState,
tabPositions: List<TabPosition>,
pageIndexMapping: (Int) -> Int = { it },
): Modifier = layout { measurable, constraints ->
if (tabPositions.isEmpty()) return@layout layout(constraints.maxWidth, 0) {}

val currentPage = minOf(tabPositions.lastIndex, pageIndexMapping(pagerState.currentPage))
val currentTab = tabPositions[currentPage]
val previousTab = tabPositions.getOrNull(currentPage - 1)
val nextTab = tabPositions.getOrNull(currentPage + 1)
val fraction = pagerState.currentPageOffset

val indicatorWidth = when {
fraction > 0 && nextTab != null -> lerp(
currentTab.width,
nextTab.width,
fraction
).roundToPx()

fraction < 0 && previousTab != null -> lerp(
currentTab.width,
previousTab.width,
-fraction
).roundToPx()

else -> currentTab.width.roundToPx()
}

val indicatorOffset = when {
fraction > 0 && nextTab != null -> lerp(
currentTab.left,
nextTab.left,
fraction
).roundToPx()

fraction < 0 && previousTab != null -> lerp(
currentTab.left,
previousTab.left,
-fraction
).roundToPx()

else -> currentTab.left.roundToPx()
}

val placeable = measurable.measure(
Constraints(
minWidth = indicatorWidth,
maxWidth = indicatorWidth,
minHeight = 0,
maxHeight = constraints.maxHeight
)
)

return@layout layout(constraints.maxWidth, maxOf(placeable.height, constraints.minHeight)) {
placeable.placeRelative(
indicatorOffset,
maxOf(constraints.minHeight - placeable.height, 0)
)
}
}

0 comments on commit 59dc842

Please sign in to comment.