Skip to content

Instantly share code, notes, and snippets.

@PSPanishetti
Created July 10, 2023 16:00
Show Gist options
  • Save PSPanishetti/c35559bdfacb6cac5446083d1845af23 to your computer and use it in GitHub Desktop.
Save PSPanishetti/c35559bdfacb6cac5446083d1845af23 to your computer and use it in GitHub Desktop.
SpiwableScrollbar
package com.postoffice.application.ui.activities
import android.graphics.Rect
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import android.view.MotionEvent.ACTION_CANCEL
import android.view.MotionEvent.ACTION_DOWN
import android.view.MotionEvent.ACTION_HOVER_MOVE
import android.view.MotionEvent.ACTION_MOVE
import android.view.MotionEvent.ACTION_UP
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.animateIntAsState
import androidx.compose.animation.core.animateSizeAsState
import androidx.compose.animation.core.animateValueAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandIn
import androidx.compose.animation.fadeIn
import androidx.compose.animation.shrinkOut
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeightIn
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.input.pointer.PointerIcon.Companion.Text
import androidx.compose.ui.input.pointer.consumeAllChanges
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.layout.boundsInParent
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInParent
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.postoffice.application.R
import com.postoffice.application.ui.ui_components.ActivityWrapper
import kotlinx.coroutines.delay
import kotlin.math.abs
class SearchCustomerActivity : ComponentActivity() {
@OptIn(ExperimentalComposeUiApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ActivityWrapper(onBackPressed = {
onBackPressedDispatcher.onBackPressed()
}, title = "Search Customer") {
Box(
modifier = Modifier
.fillMaxSize(1f)
.padding(paddingValues = it)
) {
var currentYPoint by remember { mutableStateOf(0.0f) }
var currentlyOnAlpha by remember { mutableStateOf(0) }
var bounds: MutableMap<Int, androidx.compose.ui.geometry.Rect> = mutableMapOf()
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.End,
modifier = Modifier
.fillMaxHeight(1f)
.pointerInteropFilter {
Log.d(
"KeyEvent",
"Y Loc : ${currentYPoint} and Event $it"
)
currentlyOnAlpha = getAlphaFromBounds(it.y, bounds)
if (it.action == ACTION_DOWN || it.action == ACTION_MOVE) {
currentYPoint = it.y
} else if (it.action == ACTION_UP) {
currentYPoint = -1.0f
currentlyOnAlpha = -1
}
true
}
.align(
Alignment.CenterEnd
)
.defaultMinSize(35.dp)
.padding(horizontal = 8.dp)
.onGloballyPositioned {
Log.d("Pos", "Position ${it.boundsInParent()}")
},
) {
for (temp in 65..90) {
val fontSize = animateIntAsState(
if (currentlyOnAlpha == temp) {
45
} else {
getNewSize(currentlyOnAlpha, temp)
},
label = "fontSize",
animationSpec = spring(stiffness = Spring.StiffnessHigh)
)
val color = animateColorAsState(
if (currentlyOnAlpha == temp) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.onSurface
},
label = "fontSize",
animationSpec = spring(stiffness = Spring.StiffnessHigh)
)
val padding = animateIntAsState(
if (currentlyOnAlpha == temp) {
0
} else {
0
}, label = "fontSize"
)
val paddingBottom = animateIntAsState(
if (currentlyOnAlpha == temp) {
0
} else {
0
}, label = "fontSize"
)
val paddingRight = animateIntAsState(
if (currentlyOnAlpha == temp) {
120
} else {
getNewPadding(currentlyOnAlpha, temp)
}, label = "fontSize"
)
Box(modifier = Modifier
.requiredHeightIn(25.dp)
.padding(padding.value.dp)
.padding(bottom = paddingBottom.value.dp)
.padding(end = paddingRight.value.dp)
.onGloballyPositioned {
Log.d(
"LocalPositions",
"Pos of ${
temp.toChar()
} ${it.boundsInParent()}"
)
bounds[temp] = it.boundsInParent()
}) {
Text(
text = temp.toChar().toString(),
fontSize = fontSize.value.sp,
color = color.value
)
}
}
}
}
}
}
}
private fun getNewPadding(currentlyOnAlpha: Int, paddingTopBeApplied: Int): Int {
val dif = abs(currentlyOnAlpha - paddingTopBeApplied)
return when (dif) {
1 -> 100
2 -> 80
3 -> 60
4 -> 40
5 -> 20
else -> 0
}
}
private fun getNewSize(currentlyOnAlpha: Int, paddingTopBeApplied: Int): Int {
val dif = abs(currentlyOnAlpha - paddingTopBeApplied)
return when (dif) {
1 -> 25
2 -> 20
3 -> 15
4 -> 10
else -> 10
}
}
private fun getAlphaFromBounds(
currentPos: Float,
bounds: MutableMap<Int, androidx.compose.ui.geometry.Rect>
): Int {
val maps = bounds.map {
Pair(it.key, it.value)
}
for (item in maps) {
if (currentPos >= item.second.top && currentPos <= item.second.bottom) {
return item.first
}
}
return -1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment