Skip to content

Commit fce809c

Browse files
Added SlidingBar v1.0
1 parent 08e8519 commit fce809c

File tree

4 files changed

+179
-9
lines changed

4 files changed

+179
-9
lines changed

app/src/main/java/me/nishant/slidingbar/MainActivity.kt

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,24 @@ package me.nishant.slidingbar
33
import android.os.Bundle
44
import androidx.activity.ComponentActivity
55
import androidx.activity.compose.setContent
6-
import androidx.compose.foundation.layout.fillMaxSize
6+
import androidx.compose.foundation.layout.*
77
import androidx.compose.material.MaterialTheme
88
import androidx.compose.material.Surface
99
import androidx.compose.material.Text
10-
import androidx.compose.runtime.Composable
10+
import androidx.compose.runtime.getValue
11+
import androidx.compose.runtime.mutableStateOf
12+
import androidx.compose.runtime.remember
13+
import androidx.compose.runtime.setValue
14+
import androidx.compose.ui.Alignment
15+
import androidx.compose.ui.ExperimentalComposeUiApi
1116
import androidx.compose.ui.Modifier
12-
import androidx.compose.ui.tooling.preview.Preview
17+
import androidx.compose.ui.graphics.Color
18+
import androidx.compose.ui.unit.dp
1319
import me.nishant.sliding_bar.SlidingBar
20+
import me.nishant.sliding_bar.SlidingBarDefaults
1421
import me.nishant.slidingbar.ui.theme.SlidingbarTheme
1522

23+
@ExperimentalComposeUiApi
1624
class MainActivity : ComponentActivity() {
1725
override fun onCreate(savedInstanceState: Bundle?) {
1826
super.onCreate(savedInstanceState)
@@ -23,7 +31,33 @@ class MainActivity : ComponentActivity() {
2331
modifier = Modifier.fillMaxSize(),
2432
color = MaterialTheme.colors.background
2533
) {
26-
SlidingBar()
34+
var value by remember {
35+
mutableStateOf(0f)
36+
}
37+
Column(
38+
modifier = Modifier.fillMaxSize(),
39+
horizontalAlignment = Alignment.CenterHorizontally,
40+
verticalArrangement = Arrangement.Center
41+
) {
42+
Text(
43+
text = value.toString(),
44+
style = MaterialTheme.typography.h1
45+
)
46+
Spacer(modifier = Modifier.height(16.dp))
47+
SlidingBar(
48+
value = value,
49+
onValueChanged = { value = it },
50+
modifier = Modifier
51+
.padding(horizontal = 64.dp)
52+
.fillMaxWidth(),
53+
colors = SlidingBarDefaults.colors(
54+
colorPrimary = Color.Green,
55+
colorTrack = Color.Blue
56+
),
57+
valueRange = 0f..30f,
58+
stepSize = 1f
59+
)
60+
}
2761
}
2862
}
2963
}
Lines changed: 115 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,119 @@
11
package me.nishant.sliding_bar
22

3-
import androidx.compose.material.Text
4-
import androidx.compose.runtime.Composable
3+
import android.content.res.Resources
4+
import android.util.Log
5+
import android.util.TypedValue
6+
import android.view.MotionEvent
7+
import androidx.compose.animation.core.animateDpAsState
8+
import androidx.compose.foundation.Canvas
9+
import androidx.compose.runtime.*
10+
import androidx.compose.ui.ExperimentalComposeUiApi
11+
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.geometry.Offset
13+
import androidx.compose.ui.geometry.Size
14+
import androidx.compose.ui.input.pointer.pointerInteropFilter
15+
import androidx.compose.ui.unit.Dp
16+
import androidx.compose.ui.unit.dp
17+
import kotlin.math.abs
518

19+
@ExperimentalComposeUiApi
620
@Composable
7-
fun SlidingBar() {
8-
Text(text = "Hello There!")
9-
}
21+
fun SlidingBar(
22+
value: Float,
23+
onValueChanged: (Float) -> Unit,
24+
modifier: Modifier = Modifier,
25+
enabled: Boolean = true,
26+
valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
27+
stepSize: Float = 0.01f,
28+
colors: SlidingBarColors = SlidingBarDefaults.colors()
29+
) {
30+
var pressed by remember { mutableStateOf(false) }
31+
val radius by animateDpAsState(targetValue = if (pressed) 20.dp else 0.dp)
32+
var canvasSize by remember { mutableStateOf(Size(0f, 0f)) }
33+
var downX by remember { mutableStateOf(0f) }
34+
35+
Canvas(
36+
modifier = modifier
37+
.pointerInteropFilter {
38+
val range = valueRange.endInclusive - valueRange.start
39+
val threshold = canvasSize.width / (range / stepSize)
40+
when (it.action) {
41+
MotionEvent.ACTION_DOWN -> {
42+
if (!enabled)
43+
return@pointerInteropFilter false
44+
45+
val point = Offset(
46+
(value - valueRange.start) / (valueRange.endInclusive - valueRange.start) * canvasSize.width,
47+
canvasSize.height / 2f
48+
)
49+
if (it.x in (point.x - toPx(12.dp))..(point.x + toPx(12.dp)) &&
50+
it.y in (point.y - toPx(12.dp))..(point.y + toPx(12.dp))
51+
) {
52+
pressed = true
53+
downX = it.x
54+
true
55+
} else false
56+
}
57+
MotionEvent.ACTION_MOVE -> {
58+
val dx = it.x - downX
59+
Log.d("my_debug", "Slider: dx = $dx")
60+
Log.d("my_debug", "Slider: threshold = $threshold")
61+
if (abs(dx) >= threshold) {
62+
val newValue = if (dx > 0) value + stepSize else value - stepSize
63+
if (newValue in valueRange) {
64+
Log.d("my_debug", "Slider: newValue = $newValue")
65+
onValueChanged(newValue)
66+
downX = it.x
67+
}
68+
}
69+
true
70+
}
71+
MotionEvent.ACTION_UP -> {
72+
downX = 0f
73+
pressed = false
74+
true
75+
}
76+
else -> false
77+
}
78+
}
79+
) {
80+
canvasSize = size
81+
val (width) = size
82+
val point = Offset(
83+
(value - valueRange.start) / (valueRange.endInclusive - valueRange.start) * width,
84+
center.y
85+
)
86+
drawCircle(
87+
color = colors.colorPrimary,
88+
radius = radius.toPx(),
89+
center = point,
90+
alpha = 0.2f
91+
)
92+
drawLine(
93+
color = colors.colorTrack,
94+
start = Offset(0f, center.y),
95+
end = Offset(width, center.y),
96+
strokeWidth = 2.dp.toPx(),
97+
alpha = 0.5f
98+
)
99+
drawLine(
100+
color = colors.colorTrack,
101+
start = Offset(0f, center.y),
102+
end = point,
103+
strokeWidth = 2.dp.toPx()
104+
)
105+
drawCircle(
106+
color = colors.colorPrimary,
107+
radius = 12.dp.toPx(),
108+
center = point
109+
)
110+
}
111+
}
112+
113+
private fun toPx(dp: Dp) =
114+
TypedValue.applyDimension(
115+
TypedValue.COMPLEX_UNIT_DIP,
116+
dp.value,
117+
Resources.getSystem().displayMetrics
118+
)
119+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package me.nishant.sliding_bar
2+
3+
import androidx.compose.ui.graphics.Color
4+
5+
class SlidingBarColors internal constructor(
6+
val colorPrimary: Color,
7+
val colorTrack: Color,
8+
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package me.nishant.sliding_bar
2+
3+
import androidx.compose.material.MaterialTheme
4+
import androidx.compose.runtime.Composable
5+
import androidx.compose.ui.graphics.Color
6+
7+
8+
object SlidingBarDefaults {
9+
10+
@Composable
11+
fun colors(
12+
colorPrimary: Color = MaterialTheme.colors.primary,
13+
colorTrack: Color = MaterialTheme.colors.onBackground,
14+
) = SlidingBarColors(
15+
colorPrimary = colorPrimary,
16+
colorTrack = colorTrack
17+
)
18+
}

0 commit comments

Comments
 (0)