Skip to content

Instantly share code, notes, and snippets.

@BhavyaRattan
Created September 26, 2020 14:21
Show Gist options
  • Save BhavyaRattan/4ceda4e377aa0505b85c44395503684b to your computer and use it in GitHub Desktop.
Save BhavyaRattan/4ceda4e377aa0505b85c44395503684b to your computer and use it in GitHub Desktop.
Magic Touch Recycler
class ScaleItemOnTouchListener : RecyclerView.OnItemTouchListener {
private var previousX = 0f
private var previousY = 0f
private var previousMotionX = 0f
private var previousMotionY = 0f
private object Constants {
const val SCALE_DEFAULT = 1f
const val SCALE_UP = 1.4f
const val ANIMATION_DURATION = 100L
const val DRAG_THRESHOLD = 1
}
override fun onTouchEvent(rv: RecyclerView, event: MotionEvent) {
val childView = rv.findChildViewUnder(event.x, event.y)
val previousChild = rv.findChildViewUnder(previousX, previousY)
if (childView != null) {
when (event.action) {
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
if (childView.scaleX != SCALE_UP) {
scaleUp(childView)
}
if (previousChild != null && previousChild != childView) {
scaleDown(previousChild)
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> {
scaleDown(childView)
childView.callOnClick()
}
}
previousX = childView.x
previousY = childView.y
} else if (previousChild != null && (event.action == MotionEvent.ACTION_UP || event.action == MotionEvent.ACTION_CANCEL)) {
scaleDown(previousChild)
previousX = 0f
previousY = 0f
}
}
override fun onInterceptTouchEvent(rv: RecyclerView, event: MotionEvent): Boolean {
var interceptTouch = false
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
previousMotionX = event.x
previousMotionY = event.y
}
MotionEvent.ACTION_MOVE -> {
interceptTouch = !(abs(event.x - previousMotionX) > DRAG_THRESHOLD || abs(event.y - previousMotionY) > DRAG_THRESHOLD)
}
MotionEvent.ACTION_UP -> {
previousMotionX = 0f
previousMotionY = 0f
}
}
return interceptTouch
}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
}
private fun scaleUp(view: View) {
view.animate().setDuration(ANIMATION_DURATION).scaleX(SCALE_UP).scaleY(SCALE_UP).start()
}
private fun scaleDown(view: View) {
view.animate().setDuration(ANIMATION_DURATION).scaleX(SCALE_DEFAULT).scaleY(SCALE_DEFAULT).start()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment