Skip to content
This repository has been archived by the owner on Dec 24, 2022. It is now read-only.

Commit

Permalink
Get rid of 'long' swipes, resolves #16
Browse files Browse the repository at this point in the history
  • Loading branch information
afollestad committed May 18, 2019
1 parent db4ebeb commit a61604d
Show file tree
Hide file tree
Showing 9 changed files with 15 additions and 126 deletions.
28 changes: 0 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -492,34 +492,6 @@ withSwipeActionOn<MyItem>(LEFT, RIGHT) {

With `withSwipeActionOn`, `item` in the callback is a `MyItem` instead of `Any` as well.

## Long Swipes

<img src="https://raw.githubusercontent.com/afollestad/recyclical/master/art/swipelong.gif" width="200" />

You can set long swipe actions. These actions require you to swipe an item further before releasing
to trigger. Take this block:

```kotlin
list.setup {
...
withSwipeAction(LEFT) {
icon(R.drawable.ic_archive)
text(R.string.archive)
color(R.color.md_green)
callback { index, item -> true }
}
withSwipeAction(LEFT_LONG) {
icon(R.drawable.ic_delete)
text(R.string.delete)
color(R.color.md_red)
callback { index, item -> true }
}
}
```

If you swipe just a little bit and release, the item is archived. If you swipe further, the item is
deleted. You can use `RIGHT_LONG` as well.

## Customization

As you saw above, you can use icons, text, and background colors easily. There are more details
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ import com.afollestad.recyclical.datasource.selectableDataSourceTypedOf
import com.afollestad.recyclical.itemdefinition.onChildViewClick
import com.afollestad.recyclical.setup
import com.afollestad.recyclical.swipe.SwipeLocation.LEFT
import com.afollestad.recyclical.swipe.SwipeLocation.LEFT_LONG
import com.afollestad.recyclical.swipe.SwipeLocation.RIGHT
import com.afollestad.recyclical.swipe.SwipeLocation.RIGHT_LONG
import com.afollestad.recyclical.swipe.withSwipeAction
import com.afollestad.recyclical.viewholder.SelectionStateProvider
import com.afollestad.recyclical.viewholder.isSelected
Expand Down Expand Up @@ -74,15 +72,6 @@ class MainActivity : AppCompatActivity() {

list.setup {
withSwipeAction(LEFT) {
icon(R.drawable.ic_action_star)
text(R.string.star)
color(R.color.md_orange)
callback { _, item ->
toast("Star: $item")
false
}
}
withSwipeAction(LEFT_LONG) {
icon(R.drawable.ic_action_delete)
text(R.string.delete)
color(R.color.md_red)
Expand All @@ -92,15 +81,6 @@ class MainActivity : AppCompatActivity() {
}
}
withSwipeAction(RIGHT) {
icon(R.drawable.ic_action_unread)
text(R.string.unread)
color(R.color.md_blue)
callback { _, item ->
toast("Unread: $item")
false
}
}
withSwipeAction(RIGHT_LONG) {
icon(R.drawable.ic_action_archive)
text(R.string.archive)
color(R.color.md_green)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import androidx.fragment.app.Fragment
import com.afollestad.recyclical.datasource.DataSource
import com.afollestad.recyclical.datasource.emptyDataSource
import com.afollestad.recyclical.setup
import com.afollestad.recyclical.swipe.SwipeLocation.LEFT
import com.afollestad.recyclical.swipe.SwipeLocation.RIGHT
import com.afollestad.recyclical.swipe.SwipeLocation.RIGHT_LONG
import com.afollestad.recyclical.swipe.withSwipeActionOn
import com.afollestad.recyclical.withItem
import com.afollestad.recyclicalsample.R
Expand Down Expand Up @@ -70,7 +70,7 @@ class MainFragment : Fragment() {
withEmptyView(emptyView)
withDataSource(dataSource)

withSwipeActionOn<MyListItem2>(RIGHT) {
withSwipeActionOn<MyListItem2>(LEFT, RIGHT) {
icon(R.drawable.ic_action_delete)
text(R.string.delete)
color(R.color.md_red)
Expand All @@ -79,15 +79,6 @@ class MainFragment : Fragment() {
true
}
}
withSwipeActionOn<MyListItem2>(RIGHT_LONG) {
icon(R.drawable.ic_action_archive)
text(R.string.archive)
color(R.color.md_green)
callback { _, item ->
toast("Archive: $item")
true
}
}

withItem<MyListItem, MyViewHolder>(R.layout.my_list_item) {
hasStableIds { it.id }
Expand Down
9 changes: 0 additions & 9 deletions sample/src/main/res/drawable/ic_action_star.xml

This file was deleted.

9 changes: 0 additions & 9 deletions sample/src/main/res/drawable/ic_action_unread.xml

This file was deleted.

2 changes: 0 additions & 2 deletions sample/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

<string name="delete">Delete</string>
<string name="archive">Archive</string>
<string name="unread">Unread</string>
<string name="star">Star</string>
<string name="reverse_list_order">Reverse List Order</string>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,11 @@ typealias SwipedCallback<IT> = (index: Int, item: IT) -> Boolean

/**
* Represents what position the swipe callback represents. Left means a right-to-left swipe,
* right means left-to-right swipe. A long swipe means you swipe further vs a short swipe.
* right means left-to-right swipe.
*/
enum class SwipeLocation {
LEFT,
RIGHT,
LEFT_LONG,
RIGHT_LONG
RIGHT
}

/** @author Aidan Follestad (@afollestad) */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.afollestad.recyclical.datasource.DataSource
import com.afollestad.recyclical.swipe.SwipeLocation.LEFT
import com.afollestad.recyclical.swipe.SwipeLocation.LEFT_LONG
import com.afollestad.recyclical.swipe.SwipeLocation.RIGHT
import com.afollestad.recyclical.swipe.SwipeLocation.RIGHT_LONG
import kotlin.math.abs

/** @author Aidan Follestad (@afollestad) */
internal class SwipeItemTouchListener(
Expand All @@ -39,9 +36,7 @@ internal class SwipeItemTouchListener(
private val actions = pluginData.actions

private var leftDistance: Float = -1f
private var leftIsLong: Boolean = false
private var rightDistance: Float = -1f
private var rightIsLong: Boolean = false

private var icon: Drawable? = null
private var background: ColorDrawable? = null
Expand Down Expand Up @@ -70,9 +65,8 @@ internal class SwipeItemTouchListener(
val itemClass = dataSource[index].javaClass.name
when (direction) {
ItemTouchHelper.LEFT -> {
val location = if (leftIsLong) LEFT_LONG else LEFT
val actionKeyForItem = ActionKey(location = location, itemClassName = itemClass)
val actionKeyGlobal = ActionKey(location = location, itemClassName = null)
val actionKeyForItem = ActionKey(location = LEFT, itemClassName = itemClass)
val actionKeyGlobal = ActionKey(location = LEFT, itemClassName = null)
val action = actions[actionKeyForItem] ?: actions[actionKeyGlobal] ?: return
if (action.sendToCallback(index, dataSource[index])) {
dataSource.removeAt(index)
Expand All @@ -81,9 +75,8 @@ internal class SwipeItemTouchListener(
}
}
ItemTouchHelper.RIGHT -> {
val location = if (rightIsLong) RIGHT_LONG else RIGHT
val actionKeyForItem = ActionKey(location = location, itemClassName = itemClass)
val actionKeyGlobal = ActionKey(location = location, itemClassName = null)
val actionKeyForItem = ActionKey(location = RIGHT, itemClassName = itemClass)
val actionKeyGlobal = ActionKey(location = RIGHT, itemClassName = null)
val action = actions[actionKeyForItem] ?: actions[actionKeyGlobal] ?: return
if (action.sendToCallback(index, dataSource[index])) {
dataSource.removeAt(index)
Expand All @@ -106,18 +99,14 @@ internal class SwipeItemTouchListener(
if (index == -1) return 0
val itemClass = dataSource[index].javaClass.name

var directions: Int = 0
var directions = 0
if (actions.containsKey(ActionKey(LEFT, itemClass)) ||
actions.containsKey(ActionKey(LEFT, null)) ||
actions.containsKey(ActionKey(LEFT_LONG, itemClass)) ||
actions.containsKey(ActionKey(LEFT_LONG, null))
actions.containsKey(ActionKey(LEFT, null))
) {
directions = directions or ItemTouchHelper.LEFT
}
if (actions.containsKey(ActionKey(RIGHT, itemClass)) ||
actions.containsKey(ActionKey(RIGHT, null)) ||
actions.containsKey(ActionKey(RIGHT_LONG, itemClass)) ||
actions.containsKey(ActionKey(RIGHT_LONG, null))
actions.containsKey(ActionKey(RIGHT, null))
) {
directions = directions or ItemTouchHelper.RIGHT
}
Expand Down Expand Up @@ -146,19 +135,10 @@ internal class SwipeItemTouchListener(
// Swiping to the right
rightDistance = dX

val actionKeyForItemLong = ActionKey(location = RIGHT_LONG, itemClassName = itemClass)
val actionKeyGlobalLong = ActionKey(location = RIGHT_LONG, itemClassName = null)
val actionKeyForItemShort = ActionKey(location = RIGHT, itemClassName = itemClass)
val actionKeyGlobalShort = ActionKey(location = RIGHT, itemClassName = null)
action = actions[actionKeyForItemShort] ?: actions[actionKeyGlobalShort]

rightIsLong =
(actions.containsKey(actionKeyForItemLong) || actions.containsKey(actionKeyGlobalLong)) &&
rightDistance >= (LONG_THRESHOLD_PERCENT * itemView.measuredWidth)
action = if (rightIsLong) {
actions[actionKeyForItemLong] ?: actions[actionKeyGlobalLong]
} else {
actions[actionKeyForItemShort] ?: actions[actionKeyGlobalShort]
}
icon = action?.iconDrawable ?: return
background = action.backgroundDrawable ?: ColorDrawable(DKGRAY)

Expand Down Expand Up @@ -189,19 +169,10 @@ internal class SwipeItemTouchListener(
// Swiping to the left
leftDistance = dX

val actionKeyForItemLong = ActionKey(location = LEFT_LONG, itemClassName = itemClass)
val actionKeyGlobalLong = ActionKey(location = LEFT_LONG, itemClassName = null)
val actionKeyForItemShort = ActionKey(location = LEFT, itemClassName = itemClass)
val actionKeyGlobalShort = ActionKey(location = LEFT, itemClassName = null)
action = actions[actionKeyForItemShort] ?: actions[actionKeyGlobalShort]

leftIsLong =
(actions.containsKey(actionKeyForItemLong) || actions.containsKey(actionKeyGlobalLong)) &&
abs(leftDistance) >= (LONG_THRESHOLD_PERCENT * itemView.measuredWidth)
action = if (leftIsLong) {
actions[actionKeyForItemLong] ?: actions[actionKeyGlobalLong]
} else {
actions[actionKeyForItemShort] ?: actions[actionKeyGlobalShort]
}
icon = action?.iconDrawable ?: return
background = action.backgroundDrawable ?: ColorDrawable(DKGRAY)

Expand Down Expand Up @@ -257,6 +228,5 @@ internal class SwipeItemTouchListener(

private companion object {
private const val DEFAULT_DISTANCE = -1f
private const val LONG_THRESHOLD_PERCENT = 45f / 100f
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ import com.afollestad.recyclical.RecyclicalSetup
import com.afollestad.recyclical.datasource.DataSource
import com.afollestad.recyclical.plugins.PluginData
import com.afollestad.recyclical.swipe.SwipeLocation.LEFT
import com.afollestad.recyclical.swipe.SwipeLocation.LEFT_LONG
import com.afollestad.recyclical.swipe.SwipeLocation.RIGHT
import com.afollestad.recyclical.swipe.SwipeLocation.RIGHT_LONG
import kotlin.reflect.KClass

internal const val PLUGIN_NAME = "swipe_plugin"
Expand All @@ -51,10 +49,10 @@ internal data class SwipePluginData(

fun getSwipeDirections(): Int {
var result = 0
if (actions.any { it.key.location == RIGHT || it.key.location == RIGHT_LONG }) {
if (actions.any { it.key.location == RIGHT }) {
result = result or ItemTouchHelper.RIGHT
}
if (actions.any { it.key.location == LEFT || it.key.location == LEFT_LONG }) {
if (actions.any { it.key.location == LEFT }) {
result = result or ItemTouchHelper.LEFT
}
return result
Expand Down

0 comments on commit a61604d

Please sign in to comment.