Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swipe events for SwipeDrawer behaviour #940

Merged
merged 6 commits into from
Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.mikepenz.fastadapter.app.adapters.IDraggableViewHolder
import com.mikepenz.fastadapter.app.items.SwipeableDrawerItem
import com.mikepenz.fastadapter.drag.ItemTouchCallback
import com.mikepenz.fastadapter.drag.SimpleDragCallback
import com.mikepenz.fastadapter.swipe.SimpleSwipeDrawerCallback
import com.mikepenz.fastadapter.swipe_drag.SimpleSwipeDrawerDragCallback
import com.mikepenz.fastadapter.utils.DragDropUtil
import com.mikepenz.iconics.IconicsDrawable
Expand All @@ -27,7 +28,7 @@ import io.reactivex.functions.Consumer
import kotlinx.android.synthetic.main.activity_sample.*
import java.util.*

class SwipeDrawerListActivity : AppCompatActivity(), ItemTouchCallback {
class SwipeDrawerListActivity : AppCompatActivity(), ItemTouchCallback, SimpleSwipeDrawerCallback.ItemSwipeCallback {

//save our FastAdapter
private lateinit var fastItemDrawerAdapter: FastItemAdapter<SwipeableDrawerItem>
Expand Down Expand Up @@ -57,7 +58,6 @@ class SwipeDrawerListActivity : AppCompatActivity(), ItemTouchCallback {
}

private fun share(item: SwipeableDrawerItem) {
item.shareAction = null
val position12 = fastItemDrawerAdapter.getAdapterPosition(item)
if (position12 != RecyclerView.NO_POSITION) {
// Do something intelligent here
Expand Down Expand Up @@ -108,7 +108,8 @@ class SwipeDrawerListActivity : AppCompatActivity(), ItemTouchCallback {
//and add swipe as well
touchCallback = SimpleSwipeDrawerDragCallback(
this,
ItemTouchHelper.LEFT)
ItemTouchHelper.LEFT,
this)
.withNotifyAllDrops(true)
.withSwipeLeft(80) // Width of delete button
.withSwipeRight(160) // Width of archive and share buttons
Expand Down Expand Up @@ -193,4 +194,15 @@ class SwipeDrawerListActivity : AppCompatActivity(), ItemTouchCallback {
companion object {
private val ALPHABET = arrayOf("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z")
}

override fun itemSwiped(position: Int, direction: Int) {
var directionStr = ""
if (ItemTouchHelper.LEFT == direction) directionStr = "left"
else if (ItemTouchHelper.RIGHT == direction) directionStr = "right"
println("Item $position swiped $directionStr")
}

override fun itemUnswiped(position: Int) {
println("Item $position unswiped")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import com.mikepenz.fastadapter.IItem
/**
* Created by Robb on 2020-07-04.
*/
class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs: Int = ItemTouchHelper.LEFT) : ItemTouchHelper.SimpleCallback(0, swipeDirs) {
class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs: Int = ItemTouchHelper.LEFT, private val itemSwipeCallback: ItemSwipeCallback? = null) : ItemTouchHelper.SimpleCallback(0, swipeDirs) {

// Swipe movement control
private var sensitivityFactor = 1f
Expand All @@ -27,6 +27,28 @@ class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs:
// Indicates whether the touchTransmitter has been set on the RecyclerView
private var touchTransmitterSet = false

// States of swiped items
// Key = item position
// Value = swiped direction (see {@link ItemTouchHelper})
private val swipedStates = HashMap<Int, Int>()

interface ItemSwipeCallback {

/**
* Called when a drawer has been swiped
*
* @param position position of item in the adapter
* @param direction direction the item where the drawer was swiped (see {@link ItemTouchHelper})
*/
fun itemSwiped(position: Int, direction: Int)

/**
* Called when a drawer has been un-swiped (= returns to its default position)
*
* @param position position of item in the adapter
*/
fun itemUnswiped(position: Int)
}

/**
* Enable swipe to the left until the given width has been reached
Expand Down Expand Up @@ -71,7 +93,11 @@ class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs:
}

override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
// Not used
val position = viewHolder.adapterPosition
if (position != RecyclerView.NO_POSITION && (!swipedStates.containsKey(position) || swipedStates[position] != direction)) {
itemSwipeCallback?.itemSwiped(position, direction)
swipedStates[position] = direction
}
}

override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
Expand All @@ -91,14 +117,21 @@ class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs:
touchTransmitterSet = true
}

if (viewHolder.adapterPosition == RecyclerView.NO_POSITION) {
return
}
val position = viewHolder.adapterPosition
if (position == RecyclerView.NO_POSITION) return

if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
val isLeft = dX < 0
// Careful, dX is not the delta of user's movement, it's the new offset of the swiped view's left side !
val isLeftArea = dX < 0

// If unswiped, fire event and update swiped state
if (0f == dX && swipedStates.containsKey(position)) {
itemSwipeCallback?.itemUnswiped(viewHolder.adapterPosition)
swipedStates.remove(position)
}

var swipeWidthPc = recyclerView.context.resources.displayMetrics.density / itemView.width
swipeWidthPc *= if (isLeft) swipeWidthLeftDp else swipeWidthRightDp
swipeWidthPc *= if (isLeftArea) swipeWidthLeftDp else swipeWidthRightDp

var swipeableView = itemView
if (viewHolder is IDrawerSwipeableViewHolder) swipeableView = viewHolder.swipeableView
Expand All @@ -111,7 +144,7 @@ class SimpleSwipeDrawerCallback @JvmOverloads constructor(private val swipeDirs:
* Hack to force-transmit click events to the first visible View at the clicked coordinates
* [< swiped area ] exposed sublayer ]
* Android default touch event mechanisms don't transmit these events to the sublayer :
* any click on the exposed surface just swipe the item back to where it came
* any click on the exposed surface just swipes the item back to where it came
*/
class RecyclerTouchTransmitter : View.OnTouchListener {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ import com.mikepenz.fastadapter.swipe.SimpleSwipeDrawerCallback
*/
class SimpleSwipeDrawerDragCallback @JvmOverloads constructor(
itemTouchCallback: ItemTouchCallback,
swipeDirs: Int = ItemTouchHelper.LEFT) : SimpleDragCallback(itemTouchCallback) {
swipeDirs: Int = ItemTouchHelper.LEFT,
itemSwipeCallback: SimpleSwipeDrawerCallback.ItemSwipeCallback? = null) : SimpleDragCallback(itemTouchCallback) {

private val simpleSwipeCallback: SimpleSwipeDrawerCallback
private var defaultSwipeDirs: Int = 0

init {
setDefaultSwipeDirs(swipeDirs)
simpleSwipeCallback = SimpleSwipeDrawerCallback(swipeDirs)
simpleSwipeCallback = SimpleSwipeDrawerCallback(swipeDirs, itemSwipeCallback)
}

override fun setDefaultSwipeDirs(defaultSwipeDirs: Int) {
Expand Down