Add scrollbar desing for android on MyVerticalScrollbar
This commit is contained in:
parent
c06053c5dc
commit
ffb6a4c080
1 changed files with 107 additions and 4 deletions
|
|
@ -1,16 +1,119 @@
|
|||
package mg.dot.feufaro.ui
|
||||
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.draggable
|
||||
import androidx.compose.foundation.gestures.rememberDraggableState
|
||||
import androidx.compose.foundation.gestures.scrollBy
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.blur
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
actual fun MyVerticalScrollbar (
|
||||
actual fun MyVerticalScrollbar(
|
||||
modifier: Modifier,
|
||||
scrollState: ScrollState?,
|
||||
lazyListState: LazyListState?,
|
||||
content: @Composable () -> Unit
|
||||
){
|
||||
content()
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val density = LocalDensity.current
|
||||
|
||||
var containerHeight by remember { mutableStateOf(1f) }
|
||||
val thumbHeight = 75.dp
|
||||
|
||||
val scrollPercentage by remember(scrollState, lazyListState) {
|
||||
derivedStateOf {
|
||||
if (scrollState != null && scrollState.maxValue > 0) {
|
||||
scrollState.value.toFloat() / scrollState.maxValue
|
||||
} else if (lazyListState != null) {
|
||||
val layoutInfo = lazyListState.layoutInfo
|
||||
val totalItems = layoutInfo.totalItemsCount
|
||||
if (totalItems == 0) 0f else {
|
||||
val firstVisibleItem = lazyListState.firstVisibleItemIndex
|
||||
firstVisibleItem.toFloat() / totalItems
|
||||
}
|
||||
} else {
|
||||
0f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = modifier.onGloballyPositioned { coordinates ->
|
||||
containerHeight = coordinates.size.height.toFloat()
|
||||
}
|
||||
) {
|
||||
content()
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterEnd)
|
||||
.fillMaxHeight()
|
||||
.width(15.dp)
|
||||
.background(Color.Transparent)
|
||||
) {
|
||||
val thumbHeightPx = with(density) { thumbHeight.toPx() }
|
||||
val maxOffset = containerHeight - thumbHeightPx
|
||||
val currentThumbOffset = (scrollPercentage * maxOffset).coerceIn(0f, maxOffset.coerceAtLeast(0f))
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.offset(y = with(density) { currentThumbOffset.toDp() })
|
||||
.width(10.dp)
|
||||
.height(thumbHeight)
|
||||
.align(Alignment.TopEnd)
|
||||
.clip(RoundedCornerShape(5.dp))
|
||||
.background(
|
||||
brush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
MaterialTheme.colorScheme.secondary.copy(alpha = 1f),
|
||||
MaterialTheme.colorScheme.secondary.copy(alpha = 0.75f),
|
||||
MaterialTheme.colorScheme.secondary.copy(alpha = 0.5f)
|
||||
)
|
||||
)
|
||||
)
|
||||
.draggable(
|
||||
orientation = Orientation.Vertical,
|
||||
state = rememberDraggableState { delta ->
|
||||
coroutineScope.launch {
|
||||
if (maxOffset > 0) {
|
||||
val scrollRatio = delta / maxOffset
|
||||
if (scrollState != null) {
|
||||
scrollState.scrollBy(scrollRatio * scrollState.maxValue)
|
||||
} else if (lazyListState != null) {
|
||||
val totalItems = lazyListState.layoutInfo.totalItemsCount
|
||||
lazyListState.scrollBy(scrollRatio * totalItems * 120f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopCenter)
|
||||
.padding(top = 4.dp)
|
||||
.size(6.dp)
|
||||
.blur(1.dp)
|
||||
.background(MaterialTheme.colorScheme.background, RoundedCornerShape(3.dp))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue