Add item left and right swipe background

This commit is contained in:
Shinokuni 2019-09-17 21:40:49 +02:00
parent 04a73169d7
commit c0ba878d6c
2 changed files with 78 additions and 5 deletions

View File

@ -322,10 +322,12 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
new ItemTouchHelper(new ReadropsItemTouchCallback( new ItemTouchHelper(new ReadropsItemTouchCallback(this,
new ReadropsItemTouchCallback.Config.Builder() new ReadropsItemTouchCallback.Config.Builder()
.swipeDirs(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) .swipeDirs(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)
.swipeCallback(this) .swipeCallback(this)
.leftDraw(Color.DKGRAY, R.drawable.ic_read_later)
.rightDraw(Color.DKGRAY, R.drawable.ic_read)
.build())) .build()))
.attachToRecyclerView(recyclerView); .attachToRecyclerView(recyclerView);

View File

@ -1,9 +1,20 @@
package com.readrops.app.utils package com.readrops.app.utils
import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.view.View
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import kotlin.math.abs
class ReadropsItemTouchCallback(private val config: Config) : ItemTouchHelper.SimpleCallback(config.dragDirs, config.swipeDirs) { class ReadropsItemTouchCallback(private val context: Context, private val config: Config) : ItemTouchHelper.SimpleCallback(config.dragDirs, config.swipeDirs) {
private val iconHorizontalMargin = 40
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
config.moveCallback?.onMove() config.moveCallback?.onMove()
@ -14,6 +25,53 @@ class ReadropsItemTouchCallback(private val config: Config) : ItemTouchHelper.Si
config.swipeCallback?.onSwipe(viewHolder, direction) config.swipeCallback?.onSwipe(viewHolder, direction)
} }
override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
val background: ColorDrawable
var icon: Drawable? = null
val itemView: View = viewHolder.itemView
var draw = true // variable used to draw under some conditions
// do not draw anymore if the view has reached the screen's left/right side
if (abs(dX).toInt() == itemView.right) {
draw = false
} else if (abs(dX).toInt() == 0) {
draw = true
}
// left swipe
if (dX > 0 && config.leftDraw != null && draw) {
background = ColorDrawable(config.leftDraw.bgColor)
background.setBounds(itemView.left, itemView.top, dX.toInt(), itemView.bottom)
icon = ContextCompat.getDrawable(context, config.leftDraw.icon)!!
val iconMargin = (itemView.height - icon.intrinsicHeight) / 2
icon.setBounds(itemView.left + iconHorizontalMargin, itemView.top + iconMargin,
itemView.left + iconHorizontalMargin + icon.intrinsicWidth, itemView.bottom - iconMargin)
// right swipe
} else if (dX < 0 && config.rightDraw != null && draw) {
background = ColorDrawable(config.rightDraw.bgColor)
background.setBounds(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)
icon = ContextCompat.getDrawable(context, config.rightDraw.icon)!!
val iconMargin = (itemView.height - icon.intrinsicHeight) / 2
icon.setBounds(itemView.right - iconHorizontalMargin - icon.intrinsicWidth, itemView.top + iconMargin,
itemView.right - iconHorizontalMargin, itemView.bottom - iconMargin)
} else {
background = ColorDrawable()
}
background.draw(c)
if (dX > 0)
c.clipRect(itemView.left, itemView.top, dX.toInt(), itemView.bottom)
else if (dX < 0)
c.clipRect(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)
icon?.draw(c)
}
override fun isItemViewSwipeEnabled(): Boolean { override fun isItemViewSwipeEnabled(): Boolean {
return config.swipeCallback != null return config.swipeCallback != null
} }
@ -30,10 +88,13 @@ class ReadropsItemTouchCallback(private val config: Config) : ItemTouchHelper.Si
fun onSwipe(viewHolder: RecyclerView.ViewHolder, direction: Int) fun onSwipe(viewHolder: RecyclerView.ViewHolder, direction: Int)
} }
class Config(val dragDirs: Int = 0, val swipeDirs: Int = 0, val moveCallback: MoveCallback? = null, class SwipeDraw(@ColorInt val bgColor: Int, @DrawableRes val icon: Int)
val swipeCallback: SwipeCallback? = null) {
private constructor(builder: Builder) : this(builder.dragDirs, builder.swipeDirs, builder.moveCallback, builder.swipeCallback) class Config(val dragDirs: Int = 0, val swipeDirs: Int = 0, val moveCallback: MoveCallback? = null,
val swipeCallback: SwipeCallback? = null, val leftDraw: SwipeDraw? = null, val rightDraw: SwipeDraw? = null) {
private constructor(builder: Builder) : this(builder.dragDirs, builder.swipeDirs,
builder.moveCallback, builder.swipeCallback, builder.leftDraw, builder.rightDraw)
class Builder { class Builder {
var dragDirs: Int = 0 var dragDirs: Int = 0
@ -48,6 +109,12 @@ class ReadropsItemTouchCallback(private val config: Config) : ItemTouchHelper.Si
var swipeCallback: SwipeCallback? = null var swipeCallback: SwipeCallback? = null
private set private set
var leftDraw: SwipeDraw? = null
private set
var rightDraw: SwipeDraw? = null
private set
fun dragDirs(dragDirs: Int) = apply { this.dragDirs = dragDirs } fun dragDirs(dragDirs: Int) = apply { this.dragDirs = dragDirs }
fun swipeDirs(swipeDirs: Int) = apply { this.swipeDirs = swipeDirs } fun swipeDirs(swipeDirs: Int) = apply { this.swipeDirs = swipeDirs }
@ -56,6 +123,10 @@ class ReadropsItemTouchCallback(private val config: Config) : ItemTouchHelper.Si
fun swipeCallback(swipeCallback: SwipeCallback) = apply { this.swipeCallback = swipeCallback } fun swipeCallback(swipeCallback: SwipeCallback) = apply { this.swipeCallback = swipeCallback }
fun leftDraw(@ColorInt bgColor: Int, @DrawableRes icon: Int) = apply { this.leftDraw = SwipeDraw(bgColor, icon) }
fun rightDraw(@ColorInt bgColor: Int, @DrawableRes icon: Int) = apply { this.rightDraw = SwipeDraw(bgColor, icon) }
fun build(): Config { fun build(): Config {
return Config(this) return Config(this)
} }