mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Fix Scrollbar when the list contains sticky header (#8181)
* Fix Scrollbar when the list contains sticky header * Fix VerticalFastScroller when the list contains sticky header * exposé
This commit is contained in:
		| @@ -32,6 +32,7 @@ import eu.kanade.presentation.components.BadgeGroup | ||||
| import eu.kanade.presentation.components.EmptyScreen | ||||
| import eu.kanade.presentation.components.LoadingScreen | ||||
| import eu.kanade.presentation.components.ScrollbarLazyColumn | ||||
| import eu.kanade.presentation.components.Scroller.STICKY_HEADER_KEY_PREFIX | ||||
| import eu.kanade.presentation.theme.header | ||||
| import eu.kanade.presentation.util.horizontalPadding | ||||
| import eu.kanade.presentation.util.plus | ||||
| @@ -85,7 +86,7 @@ private fun MigrateSourceList( | ||||
|     ScrollbarLazyColumn( | ||||
|         contentPadding = contentPadding + topPaddingValues, | ||||
|     ) { | ||||
|         stickyHeader(key = "header") { | ||||
|         stickyHeader(key = STICKY_HEADER_KEY_PREFIX) { | ||||
|             Row( | ||||
|                 modifier = Modifier | ||||
|                     .background(MaterialTheme.colorScheme.background) | ||||
|   | ||||
| @@ -42,9 +42,10 @@ import androidx.compose.ui.unit.Dp | ||||
| import androidx.compose.ui.unit.IntOffset | ||||
| import androidx.compose.ui.unit.LayoutDirection | ||||
| import androidx.compose.ui.unit.dp | ||||
| import androidx.compose.ui.util.fastFirstOrNull | ||||
| import androidx.compose.ui.util.fastForEach | ||||
| import androidx.compose.ui.util.fastMaxBy | ||||
| import eu.kanade.presentation.util.plus | ||||
| import eu.kanade.presentation.components.Scroller.STICKY_HEADER_KEY_PREFIX | ||||
| import kotlinx.coroutines.channels.BufferOverflow | ||||
| import kotlinx.coroutines.flow.MutableSharedFlow | ||||
| import kotlinx.coroutines.flow.collectLatest | ||||
| @@ -53,6 +54,11 @@ import kotlin.math.max | ||||
| import kotlin.math.min | ||||
| import kotlin.math.roundToInt | ||||
|  | ||||
| /** | ||||
|  * Draws vertical fast scroller to a lazy list | ||||
|  * | ||||
|  * Set key with [STICKY_HEADER_KEY_PREFIX] prefix to any sticky header item in the list. | ||||
|  */ | ||||
| @Composable | ||||
| fun VerticalFastScroller( | ||||
|     listState: LazyListState, | ||||
| @@ -386,7 +392,8 @@ private fun computeScrollRange(state: LazyGridState): Int { | ||||
| private fun computeScrollOffset(state: LazyListState): Int { | ||||
|     if (state.layoutInfo.totalItemsCount == 0) return 0 | ||||
|     val visibleItems = state.layoutInfo.visibleItemsInfo | ||||
|     val startChild = visibleItems.first() | ||||
|     val startChild = visibleItems | ||||
|         .fastFirstOrNull { (it.key as? String)?.startsWith(STICKY_HEADER_KEY_PREFIX)?.not() ?: true }!! | ||||
|     val endChild = visibleItems.last() | ||||
|     val minPosition = min(startChild.index, endChild.index) | ||||
|     val maxPosition = max(startChild.index, endChild.index) | ||||
| @@ -401,13 +408,18 @@ private fun computeScrollOffset(state: LazyListState): Int { | ||||
| private fun computeScrollRange(state: LazyListState): Int { | ||||
|     if (state.layoutInfo.totalItemsCount == 0) return 0 | ||||
|     val visibleItems = state.layoutInfo.visibleItemsInfo | ||||
|     val startChild = visibleItems.first() | ||||
|     val startChild = visibleItems | ||||
|         .fastFirstOrNull { (it.key as? String)?.startsWith(STICKY_HEADER_KEY_PREFIX)?.not() ?: true }!! | ||||
|     val endChild = visibleItems.last() | ||||
|     val laidOutArea = endChild.bottom - startChild.top | ||||
|     val laidOutRange = abs(startChild.index - endChild.index) + 1 | ||||
|     return (laidOutArea.toFloat() / laidOutRange * state.layoutInfo.totalItemsCount).roundToInt() | ||||
| } | ||||
|  | ||||
| object Scroller { | ||||
|     const val STICKY_HEADER_KEY_PREFIX = "sticky:" | ||||
| } | ||||
|  | ||||
| private val ThumbLength = 48.dp | ||||
| private val ThumbThickness = 8.dp | ||||
| private val ThumbShape = RoundedCornerShape(ThumbThickness / 2) | ||||
|   | ||||
| @@ -62,11 +62,18 @@ import androidx.compose.ui.platform.LocalLayoutDirection | ||||
| import androidx.compose.ui.tooling.preview.Preview | ||||
| import androidx.compose.ui.unit.LayoutDirection | ||||
| import androidx.compose.ui.unit.dp | ||||
| import androidx.compose.ui.util.fastFirstOrNull | ||||
| import androidx.compose.ui.util.fastSumBy | ||||
| import eu.kanade.presentation.components.Scroller.STICKY_HEADER_KEY_PREFIX | ||||
| import kotlinx.coroutines.channels.BufferOverflow | ||||
| import kotlinx.coroutines.flow.MutableSharedFlow | ||||
| import kotlinx.coroutines.flow.collectLatest | ||||
|  | ||||
| /** | ||||
|  * Draws horizontal scrollbar to a LazyList. | ||||
|  * | ||||
|  * Set key with [STICKY_HEADER_KEY_PREFIX] prefix to any sticky header item in the list. | ||||
|  */ | ||||
| fun Modifier.drawHorizontalScrollbar( | ||||
|     state: LazyListState, | ||||
|     reverseScrolling: Boolean = false, | ||||
| @@ -74,6 +81,11 @@ fun Modifier.drawHorizontalScrollbar( | ||||
|     positionOffsetPx: Float = 0f, | ||||
| ): Modifier = drawScrollbar(state, Orientation.Horizontal, reverseScrolling, positionOffsetPx) | ||||
|  | ||||
| /** | ||||
|  * Draws vertical scrollbar to a LazyList. | ||||
|  * | ||||
|  * Set key with [STICKY_HEADER_KEY_PREFIX] prefix to any sticky header item in the list. | ||||
|  */ | ||||
| fun Modifier.drawVerticalScrollbar( | ||||
|     state: LazyListState, | ||||
|     reverseScrolling: Boolean = false, | ||||
| @@ -106,7 +118,7 @@ private fun Modifier.drawScrollbar( | ||||
|         0f | ||||
|     } else { | ||||
|         items | ||||
|             .first() | ||||
|             .fastFirstOrNull { (it.key as? String)?.startsWith(STICKY_HEADER_KEY_PREFIX)?.not() ?: true }!! | ||||
|             .run { | ||||
|                 val startPadding = if (reverseDirection) layoutInfo.afterContentPadding else layoutInfo.beforeContentPadding | ||||
|                 startPadding + ((estimatedItemSize * index - offset) / totalSize * viewportSize) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user