Skip to content

Instantly share code, notes, and snippets.

@wakaztahir
Created June 28, 2021 04:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wakaztahir/f1421f45ebe7fea1bb27ca51034fe5d1 to your computer and use it in GitHub Desktop.
Save wakaztahir/f1421f45ebe7fea1bb27ca51034fe5d1 to your computer and use it in GitHub Desktop.
package com.wakaztahir.timeline.ui.components.commons
import android.view.MotionEvent
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.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.LinearProgressIndicator
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
@ExperimentalComposeUiApi
@Composable
fun Seekbar(
modifier: Modifier = Modifier,
barProgress: Float,
onProgressChange: (Float) -> Unit,
barColor: Color = MaterialTheme.colors.primary,
barBackgroundColor: Color = MaterialTheme.colors.background,
thumbSize: IntSize = IntSize(16, 16),
thumbShape: Shape = RoundedCornerShape(50),
thumbColor: Color = MaterialTheme.colors.onBackground,
enabled: Boolean = true
) {
val barWidth = remember {
mutableStateOf(0)
}
val density = LocalDensity.current
val barWidthInDp = remember(barWidth.value) {
with(density) {
barWidth.value.toDp()
}
}
val thumbX = remember(barWidth.value, barProgress, thumbSize, thumbShape) {
with(density) {
((barProgress * barWidth.value)).toDp()
}
}
val draggableState = rememberDraggableState {
var already = thumbX
already += with(density) {
it.toDp()
}
if (already.value > 0) {
if (already.value < barWidthInDp.value) {
onProgressChange((already.value / barWidthInDp.value))
} else {
onProgressChange(1f)
}
} else {
onProgressChange(0f)
}
}
Box(modifier = modifier.onGloballyPositioned {
barWidth.value = it.size.width
}) {
LinearProgressIndicator(
modifier = Modifier
.align(Alignment.Center)
.pointerInteropFilter {
when (it.action) {
MotionEvent.ACTION_DOWN -> {
onProgressChange(it.x / barWidth.value)
}
}
false
}
.fillMaxWidth(),
progress = barProgress,
color = barColor,
backgroundColor = barBackgroundColor
)
Box(
modifier = Modifier
.size(thumbSize.width.dp, thumbSize.height.dp)
.offset(thumbX, (0).dp)
.background(thumbColor, thumbShape)
.clip(thumbShape)
.draggable(
draggableState,
Orientation.Horizontal,
enabled
)
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment