Created
March 25, 2019 15:42
-
-
Save wesleybliss/a802d5fa4c4cc82bde9de2bcedb29b05 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.graphics.Canvas | |
import android.graphics.Color | |
import android.graphics.drawable.ColorDrawable | |
import android.graphics.drawable.Drawable | |
import androidx.recyclerview.widget.ItemTouchHelper | |
import androidx.recyclerview.widget.RecyclerView | |
import com.splashthat.host.R | |
import com.splashthat.host.api.Identifiable | |
import com.splashthat.host.extensions.getColorDrawable | |
@Suppress("MemberVisibilityCanBePrivate") | |
class RecyclerViewTouchHelper<T : Identifiable>( | |
val provideItem: (Int) -> T?, | |
val onSwipeLeft: ((Int) -> Unit)? = null, | |
val onSwipeRight: ((Int) -> Unit)? = null, | |
val onSwipeUp: ((Int) -> Unit)? = null, | |
val onSwipeDown: ((Int) -> Unit)? = null | |
) : ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) { | |
private var icon: Drawable? = null | |
private var iconLeft = 0 | |
private var iconRight = 0 | |
private var background = ColorDrawable(Color.TRANSPARENT) | |
/** | |
* Always returns false b/c we're not handling movement events | |
*/ | |
override fun onMove( | |
recyclerView: RecyclerView, | |
viewHolder: RecyclerView.ViewHolder, | |
target: RecyclerView.ViewHolder | |
) : Boolean = false | |
/** | |
* Triggers after a full "swipe" gesture completes | |
*/ | |
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { | |
val position = viewHolder.adapterPosition | |
when (direction) { | |
ItemTouchHelper.LEFT -> onSwipeLeft?.invoke(position) | |
ItemTouchHelper.RIGHT -> onSwipeRight?.invoke(position) | |
ItemTouchHelper.UP -> onSwipeUp?.invoke(position) | |
ItemTouchHelper.DOWN -> onSwipeDown?.invoke(position) | |
} | |
} | |
/** | |
* Handles drawing the child view behind the real view | |
*/ | |
override fun onChildDraw( | |
c: Canvas, | |
recyclerView: RecyclerView, | |
viewHolder: RecyclerView.ViewHolder, | |
deltaX: Float, | |
deltaY: Float, | |
actionState: Int, | |
isCurrentlyActive: Boolean | |
) { | |
super.onChildDraw(c, recyclerView, viewHolder, deltaX, deltaY, actionState, isCurrentlyActive) | |
// If a non-swiping gesture is happening, ignore | |
if (actionState != ItemTouchHelper.ACTION_STATE_SWIPE) return | |
val itemView = viewHolder.itemView | |
val direction = when { | |
deltaX > 0 -> ItemTouchHelper.RIGHT | |
deltaX < 0 -> ItemTouchHelper.LEFT | |
else -> null | |
} | |
// Icon to show underneath the view being dragged | |
icon = when (direction) { | |
ItemTouchHelper.RIGHT -> recyclerView.context.getDrawable(R.drawable.zzz_album) | |
ItemTouchHelper.LEFT -> recyclerView.context.getDrawable(R.drawable.zzz_trash) | |
else -> null | |
} | |
var iconMargin = 0 | |
var iconTop = 0 | |
var iconBottom = 0 | |
icon?.also { | |
iconMargin = (itemView.height - it.intrinsicHeight) / 2 | |
iconTop = itemView.top + (itemView.height - it.intrinsicHeight) / 2 | |
iconBottom = iconTop + it.intrinsicHeight | |
} | |
when (direction) { | |
ItemTouchHelper.RIGHT -> { | |
icon = recyclerView.context.getDrawable(R.drawable.zzz_check) | |
iconLeft = itemView.left + iconMargin | |
iconRight = (icon?.intrinsicWidth ?: 0) + iconMargin | |
background = recyclerView.context.getColorDrawable(R.color.money) | |
background.setBounds( | |
itemView.left, | |
itemView.top, | |
itemView.left + deltaX.toInt(), | |
itemView.bottom | |
) | |
} | |
ItemTouchHelper.LEFT -> { | |
icon = recyclerView.context.getDrawable(R.drawable.zzz_trash) | |
iconLeft = itemView.right - iconMargin - (icon?.intrinsicWidth ?: 0) | |
iconRight = itemView.right - iconMargin | |
background = recyclerView.context.getColorDrawable(R.color.hollywood) | |
background.setBounds( | |
itemView.right + deltaX.toInt(), | |
itemView.top, | |
itemView.right, | |
itemView.bottom | |
) | |
} | |
else -> { | |
icon = null | |
background = ColorDrawable(Color.TRANSPARENT) | |
background.setBounds(0, 0, 0, 0) | |
} | |
} | |
// Draw the background color first | |
background.draw(c) | |
// Draw the icon over the background | |
icon?.setBounds(iconLeft, iconTop, iconRight, iconBottom) | |
icon?.draw(c) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment