Squishy is a lightweight library for controlling the overscroll effect of parent containers or child composables based on user input. It provides parameters to customize the behavior of overscroll effects.
squishy.mp4
Add this to your root build.gradle.kts
:
repositories {
maven { setUrl("https://jitpack.io") }
}
Add this to your module build.gradle.kts
:
dependencies {
implementation("com.github.iamjosephmj:Squishy:1.0.3")
}
BaseOverscrollEffect
is an abstract class for handling overscroll effects in a composable's parent container or child composables. It provides infrastructure for custom overscroll and fling behaviors using coroutines and animations.
- Overscroll Management: Control the overscroll effect for smooth interactions.
- Customizable Animations: Use
Animatable
andAnimationSpec
for custom animations. - Orientation Support: Supports vertical and horizontal orientations.
- Modifiable Behavior: Provides modifiers for easy integration and customization in Jetpack Compose.
Applies overscroll effects to a composable.
@OptIn(ExperimentalFoundationApi::class)
fun Modifier.overScroll(
isParentOverScrollEnabled: Boolean = true,
overscrollEffect: BaseOverscrollEffect,
orientation: Orientation = Orientation.Vertical,
flingBehavior: FlingBehavior? = null
): Modifier
isParentOverScrollEnabled
: Enable or disable parent overscroll.overscrollEffect
: Custom overscroll behavior.orientation
: Scroll orientation (Vertical or Horizontal).flingBehavior
: Custom fling behavior (optional).
Allows child composables to utilize the overscroll effect from the parent container.
fun Modifier.childOverScrollSupport(
overscrollEffect: BaseOverscrollEffect
): Modifier
overscrollEffect
: Custom overscroll behavior for child composables.
val overscrollEffect = MyCustomOverscrollEffect(
scope = rememberCoroutineScope(),
orientation = Orientation.Vertical,
maxOverscroll = 300f,
animatable = remember { Animatable(0f) },
animationSpec = tween(durationMillis = 500)
)
Column(
modifier = Modifier
.fillMaxSize()
.overScroll(
isParentOverScrollEnabled = true,
overscrollEffect = overscrollEffect,
orientation = Orientation.Vertical
)
) {
// Content here
}
Column(
modifier = Modifier
.fillMaxSize()
.overScroll(
isParentOverScrollEnabled = false,
overscrollEffect = overscrollEffect,
orientation = Orientation.Vertical
)
) {
for (item in 1..50) {
Button(
onClick = {},
modifier = Modifier
.fillMaxWidth()
.childOverScrollSupport(overScroll)
.height(50.dp)
.padding(1.dp)
) {
Text(text = "item$item", textAlign = TextAlign.Center)
}
}
}
- Add
BaseOverscrollEffect
to your project. - Create custom overscroll effects by extending
BaseOverscrollEffect
. - Apply the
overScroll
andchildOverScrollSupport
modifiers to your composables.
class PushDownOverscrollEffect(
scope: CoroutineScope,
maxOverscroll: Float,
orientation: Orientation,
animatable: Animatable<Float, out AnimationVector>,
animationSpec: AnimationSpec<Float>
) : BaseOverscrollEffect(
scope = scope,
maxOverscroll = maxOverscroll,
orientation = orientation,
animatable = animatable,
animationSpec = animationSpec
) {
override val effectModifier: Modifier
get() = if (orientation == Orientation.Vertical) {
super.effectModifier
.offset { IntOffset(0, getOffsetValue().roundToInt()) }
} else {
super.effectModifier.offset { IntOffset(getOffsetValue().roundToInt(), 0) }
}
}
@Composable
fun rememberPushDownOverscrollEffect(
maxOverscroll: Float = 1000f,
orientation: Orientation = Orientation.Vertical,
animationSpec: AnimationSpec<Float> = tween(500),
animatable: Animatable<Float, out AnimationVector> = Animatable(0f)
): BaseOverscrollEffect {
val scope = rememberCoroutineScope()
return remember {
PushDownOverscrollEffect(
scope,
maxOverscroll,
orientation,
animatable,
animationSpec
)
}
}
val pushDownOverscrollEffect = rememberPushDownOverscrollEffect()
Column(
modifier = Modifier
.fillMaxSize()
.overScroll(
overscrollEffect = pushDownOverscrollEffect
)
) {
// Content here
}
- The library doesn't work with
LazyList
.
If you encounter any issues with Squishy, please file a GitHub issue with as many details as possible, including example code or steps to reproduce the issue. For feature requests, submit an issue or a pull request.
- Ensure all tests pass.
- Raise a PR to the
develop
branch. - Ensure no issues from Android Studio lint analyzer.