Skip to content

Commit

Permalink
Merge pull request #7 from rprunskas/pull_request_destroy
Browse files Browse the repository at this point in the history
Added posibility detach recyclerview and clean up other resources
  • Loading branch information
Jamie Sanson authored Feb 18, 2021
2 parents 0ee158b + c06d70f commit 3cbdaf4
Showing 1 changed file with 37 additions and 22 deletions.
59 changes: 37 additions & 22 deletions covert/src/main/java/nz/co/trademe/covert/Covert.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ import android.graphics.drawable.Drawable
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.annotation.ColorRes
import androidx.annotation.DimenRes
import androidx.annotation.DrawableRes
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import androidx.core.content.ContextCompat
import androidx.interpolator.view.animation.FastOutLinearInInterpolator
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.ItemTouchHelper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import io.reactivex.BackpressureStrategy
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.subjects.PublishSubject
import nz.co.trademe.covert.canvas.CanvasDrawable
import nz.co.trademe.covert.canvas.*
import nz.co.trademe.covert.model.AnimationData
import nz.co.trademe.covert.model.ColorChange
Expand Down Expand Up @@ -107,12 +107,16 @@ class Covert private constructor(
private var listenerNotified: Boolean = false
private var isReturning: Boolean = false
private var flagRenderedOnReturn: Boolean = false

// Ternary variable representing if the viewHolder started out swiping as active or inactive
private var isViewHolderCurrentlyActive: Boolean? = null

// Optimisation for not notifying the RecyclerView at more than 60fps
private val updateSubject = PublishSubject.create<Int>()

private val itemTouchHelper: ItemTouchHelper
private val updateDisposable: Disposable

companion object {
const val SKIP_FULL_BIND_PAYLOAD = "swipe_action_skip_full_bind_payload"

Expand All @@ -121,7 +125,9 @@ class Covert private constructor(
}

init {
ItemTouchHelper(this).attachToRecyclerView(recyclerView)
itemTouchHelper = ItemTouchHelper(this).apply {
attachToRecyclerView(recyclerView)
}

recyclerView.itemAnimator = null

Expand All @@ -135,7 +141,7 @@ class Covert private constructor(

// Optimization - The following subject ensures that we only ever notify the RecyclerView of item
// changes at 60fps max
updateSubject
updateDisposable = updateSubject
.toFlowable(BackpressureStrategy.DROP)
.debounce(TIME_PER_FRAME_MS, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
Expand All @@ -144,6 +150,14 @@ class Covert private constructor(
}
}

/**
* Cleans up and detaches recycler view
*/
fun destroy() {
itemTouchHelper.attachToRecyclerView(null)
updateDisposable.dispose()
}

/**
* Constructs a list of [CanvasDrawable]s which represent the inactive state, i.e the state which
* starts as inactive and proceeds to active via a circular reveal animation.
Expand All @@ -156,17 +170,17 @@ class Covert private constructor(

// Background icon lift drawable
val backgroundIconDrawable = IconLiftCanvasDrawable(
liftStartProportion = ANIMATION_THRESHOLD_PROPORTION - ICON_LIFT_ANIMATION_OFFSET_PROPORTION,
bounceAnimationData = AnimationData(
startProportion = SWIPE_THRESHOLD_PROPORTION,
duration = BOUNCE_DURATION
),
maxIconScaleProportion = MAX_LIFT_SCALE,
iconInsetPx = iconInset.toInt(),
iconSizePx = ICON_DEFAULT_SIZE_DP.toPx(context).toInt(),
iconColor = ContextCompat.getColor(context, covertConfig.inactiveIcon.startColorRes),
icon = (VectorDrawableCompat.create(context.resources, covertConfig.inactiveIcon.iconRes, context.theme) as Drawable).mutate(),
clipStartProportion = null
liftStartProportion = ANIMATION_THRESHOLD_PROPORTION - ICON_LIFT_ANIMATION_OFFSET_PROPORTION,
bounceAnimationData = AnimationData(
startProportion = SWIPE_THRESHOLD_PROPORTION,
duration = BOUNCE_DURATION
),
maxIconScaleProportion = MAX_LIFT_SCALE,
iconInsetPx = iconInset.toInt(),
iconSizePx = ICON_DEFAULT_SIZE_DP.toPx(context).toInt(),
iconColor = ContextCompat.getColor(context, covertConfig.inactiveIcon.startColorRes),
icon = (VectorDrawableCompat.create(context.resources, covertConfig.inactiveIcon.iconRes, context.theme) as Drawable).mutate(),
clipStartProportion = null
)

// Circular reveal drawable
Expand Down Expand Up @@ -301,7 +315,8 @@ class Covert private constructor(

if (drawables.isNotEmpty()) {
// Find the total margin applied to the ViewHolder such that animations are always draw within itemView bounds
val viewHolderMarginY = (viewHolder.itemView.layoutParams as? RecyclerView.LayoutParams)?.let { it.leftMargin + it.rightMargin } ?: 0
val viewHolderMarginY = (viewHolder.itemView.layoutParams as? RecyclerView.LayoutParams)?.let { it.leftMargin + it.rightMargin }
?: 0

val parentMetrics = ParentMetrics(
width = viewHolder.itemView.measuredWidth.toFloat() - viewHolderMarginY.toFloat(),
Expand Down

0 comments on commit 3cbdaf4

Please sign in to comment.