Skip to content

Instantly share code, notes, and snippets.

@amyu
Last active June 26, 2018 03:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amyu/06c98ce374c212a74477062493910750 to your computer and use it in GitHub Desktop.
Save amyu/06c98ce374c212a74477062493910750 to your computer and use it in GitHub Desktop.
class MovableConstraintLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), GestureDetector.OnGestureListener {
private val detector: GestureDetectorCompat = GestureDetectorCompat(context, this)
override fun onShowPress(e: MotionEvent?) {
}
override fun onSingleTapUp(e: MotionEvent?): Boolean = true
override fun onDown(e: MotionEvent?): Boolean = true
override fun onFling(
e1: MotionEvent?,
e2: MotionEvent?,
velocityX: Float,
velocityY: Float
): Boolean = true
override fun onScroll(
e1: MotionEvent?,
e2: MotionEvent?,
distanceX: Float,
distanceY: Float
): Boolean = true.also { _ ->
if (distanceY != 0f) {
y += -distanceY * 0.5f
}
}
override fun onLongPress(e: MotionEvent?) {
}
private var threshold: Float = 0f
private var initializeTop: Float = 0f
var onOverScrollListener: (() -> Unit)? = null
override fun onLayout(
changed: Boolean,
left: Int,
top: Int,
right: Int,
bottom: Int
) {
super.onLayout(changed, left, top, right, bottom)
initializeTop = top.toFloat()
threshold = (bottom - top) * 0.08f
}
override fun onTouchEvent(event: MotionEvent?): Boolean =
if (detector.onTouchEvent(event)) {
true
} else {
super.onTouchEvent(event)
}.also { _ ->
if (event?.action == MotionEvent.ACTION_UP) {
when {
y.absoluteValue > threshold -> {
onOverScrollListener?.invoke()
}
y != initializeTop -> {
ViewCompat.animate(this)
.setDuration(100)
.translationY(initializeTop)
.start()
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment