After swiping an item in RecyclerView I want it to go back without swiping it back manually.
Here is an swipeable item in RecyclerView.
Item in RecyclerView
Swiping...
After swipe event I want this item to go back, as if it was swiped not far enough, but event must happen. How can I do this?
After swipe
Here is my SwipeHelper, which keeps background static:
abstract class ProfileSwipeHelper : ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT
) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return true
}
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
if (viewHolder != null) {
ItemTouchHelper.Callback.getDefaultUIUtil().onSelected((viewHolder as ProfilesAdapter.ViewHolder).foreground)
}
}
override fun onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
getDefaultUIUtil().onDraw(c, recyclerView,
(viewHolder as ProfilesAdapter.ViewHolder).foreground, dX, dY,
actionState, isCurrentlyActive)
}
override fun onChildDrawOver(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder?,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
getDefaultUIUtil().onDrawOver(
c, recyclerView,
(viewHolder as ProfilesAdapter.ViewHolder).foreground, dX, dY,
actionState, isCurrentlyActive)
}
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
getDefaultUIUtil().clearView((viewHolder as ProfilesAdapter.ViewHolder).foreground)
}
}
And here onSwiped event in main activity, only with Toast:
//Main Activity
val context : Context = this
val deleteSwipeHandler1 = object : ProfileSwipeHelper() {
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
Toast.makeText(context, "swiped", Toast.LENGTH_SHORT).show()
}
}
ItemTouchHelper(deleteSwipeHandler1).attachToRecyclerView(rv_profiles)
You can use Multiswipe library. Read complete explanations here. If you want to use Java read this. Below is
a concise explanation without using complete options of this library:
add jitpack and Multiswipe library to your project:
in settings.gradle or root build.gradle:
repositories {
//...
maven { url 'https://jitpack.io' }
}
in app's build.gradle:
dependencies {
implementation 'com.github.ygngy:multiswipe:1.2.1'
}
implement MultiSwipe in ViewHolder:
import androidx.recyclerview.widget.RecyclerView
import android.view.View
import com.github.ygngy.multiswipe.MultiSwipe
import com.github.ygngy.multiswipe.LeftSwipeList
import com.github.ygngy.multiswipe.RightSwipeList
class ViewHolder(private val view: View) : RecyclerView.ViewHolder(view), MultiSwipe {
var mLeftSwipeList: LeftSwipeList? = null
var mRightSwipeList: RightSwipeList? = null
// todo other ViewHolder codes...
fun bind() {
// Each swipe contains of at least an id and an icon
val likeSwipe = Swipe(
context = context, // context used to extract default colors and margins from resources
id = SWIPE_TO_LIKE_ID, // swipe id will be sent to onSwipeDone when swipe is completed
activeIcon = getDrawable(R.drawable.ic_like_24)!!, // swipe icon
activeLabel = getString(R.string.like), // OPTIONAL swipe label
acceptIcon = getDrawable(R.drawable.ic_like_accept_24)!!,// OPTIONAL icon used when swipe displacement is greater than "accept boundary"
acceptLabel = getString(R.string.like_accept),// OPTIONAL label used when swipe swipe displacement is greater than "accept boundary"
inactiveIcon = getDrawable(R.drawable.ic_disabled_like_24)!!// OPTIONAL icon used when this swipe could be next swipe
)
// Create other swipes (shareSwipe, copySwipe, ...) in a similar way.
// If row has left swipes, create left swipe list in the desired order like below:
mLeftSwipeList = LeftSwipeList (shareSwipe, copySwipe, cutSwipe)
// If row has right swipes, create right swipe list in the desired order like below:
mRightSwipeList = RightSwipeList (likeSwipe, editSwipe, delSwipe)
}
// Don't recreate swipes or any object here
override val leftSwipeList: LeftSwipeList?
get() = mLeftSwipeList
// Don't recreate swipes or any object here
override val rightSwipeList: RightSwipeList?
get() = mRightSwipeList
// Here handle swipe event and/or return some data to MultiSwipeListener
override fun onSwipeDone(swipeId: Int): Any? {
// Instead you may choose to only return data
// from this method to consume event at Activity or Fragment
when(swipeId) {
SWIPE_TO_SHARE_ID -> {
// todo share
}
SWIPE_TO_COPY_ID -> {
// todo copy
}
//...
}
return MyData()// return any data to Activity or Fragment
}
}
attach library to recyclerview at activity or fragment:
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.github.ygngy.multiswipe.MultiSwipeListener
import com.github.ygngy.multiswipe.SwipeDirection
import com.github.ygngy.multiswipe.multiSwiping // importing extension function
class DemoActivity : AppCompatActivity() {
// todo other activity codes...
override fun onCreate(savedInstanceState: Bundle?) {
// todo other onCreate codes...
// attaching Multiswipe to RecycerView
recyclerView.multiSwiping(
swipeThreshold = 0.5f, // OPTIONAL, the fraction of view for complete swipe threshold
object: MultiSwipeListener { // OPTIONAL listener
// This method is called after onSwipeDone of ViewHolder
// and data is the returned value of onSwipeDone of ViewHolder
override fun onSwipeDone(swipeId: Int, data: Any?) {
// data is the return value of "ViewHolder.onSwipeDone"
// cast to data you returned from "ViewHolder.onSwipeDone"
val myData = data as MyData?
when(swipeId) {
SWIPE_TO_SHARE_ID -> shareItem(myData)
SWIPE_TO_COPY_ID -> copyItem(myData)
//...
}
}
/***
This method will be called when direction changes in each swipe.
This method could be used to hide on screen widgets such as FABs.
direction may be:
- START (when user opens start side of view),
- END (when user opens end side of view),
- NONE (when swipe is closing without user interaction)
***/
override fun swiping(direction: SwipeDirection, swipeListSize: Int) {
// here i hide FAB when user is swiping end side actively
if (direction == SwipeDirection.END) fab.hide() else fab.show()
}
})
}
}
Related
I am currently trying to implement a RecyclerView list with drag and drop reordering. For this I use the ItemTouchHelper.SimpleCallback
class SoftkeyScreenListReorderHelperCallback(
private val adapter: SoftkeyScreenListAdapter
) : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.START or ItemTouchHelper.END, 0) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return adapter.itemMoved(viewHolder.bindingAdapterPosition, target.bindingAdapterPosition)
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
}
My Adapter got the itemMoved() method, which is called in the onMove() method in the callback. Here I just swap the items and notify the adapter about the change.
fun itemMoved(fromPosition: Int, toPosition: Int): Boolean {
Collections.swap(list, fromPosition, toPosition)
notifyItemMoved(fromPosition, toPosition)
return true
}
For my RecyclerView I implemented the following
binding.recyclerview.apply {
[...] // adapter init
myAdapter.setHasStableIds(true)
adapter = myAdapter
val touchHelper = ItemTouchHelper(SoftkeyScreenListReorderHelperCallback(adapter as SoftkeyScreenListAdapter))
touchHelper?.attachToRecyclerView(this)
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
setHasFixedSize(true)
}
It works, but I always get flickering for the items below (after) the new item position. Assume I have 5 Items {1,2,3,4,5} and want to swap 1 with 3, then 4 and 5 are flickering. 1, 2 and 3 don't.
I already set the recyclerview size fixed, enabled stable ids and disabled animations, but it does not help. Does anyone has a clue what could be the reason for that and how to fix?
try this
recyclerView.getItemAnimator().setChangeDuration(0);
Possibly, you are getting or loading your data from a place or using a library that requires some time. If that is the case, this answer could help
Try this:
After adapter initialization:
adapter.setHasStableIds(true);
In adapter class:
#Override
public long getItemId(int position) {
return itemList.get(position).hashCode();
}
Hello fellow programmers!
I am currently facing problem with RecyclerView's add animation with smooth scroll simulataneously.
Problem
I have implemented RecyclerView with ListAdapter and DiffUtil for cool animations (insert, remove). The problem is that I can't get it to smooth scroll to added position without cancelling insert animation.
User is supposed to type in 'exercise name' and then push 'add' button to add it to current 'exercise list'. Then this exercise should be added to RecyclerView list. Everything works fine here, but I can't achieve smooth scroll to new item position without cancelling (or accelerating) insert animation.
viewModel.exerciseListLiveData.observe(viewLifecycleOwner, {
adapter.submitList(it) {
// Cancels insert animation (or accelerates it rapidly) - bad UX...
layoutManager.smoothScrollToPosition(recyclerView, RecyclerView.State(), 0)
}
})
On the other hand, substituting smoothScrollToPosition with scrollToPosition works fine but when there's more items (recycler's view is filled from top to bottom) it blinks on scroll. I know it's rather jump than smooth scroll but then, why is it working with add animation so it doesn't cancel or accelerate?
viewModel.exerciseListLiveData.observe(viewLifecycleOwner, {
adapter.submitList(it) {
// Works fine (recyclerView is scrolling to added position)
// but when there's no room to display more items - it scrolls to it with blink...
// which I simply can't stand!
layoutManager.smoothScrollToPosition(recyclerView, RecyclerView.State(), 0)
}
})
Possible solution?
I'm supposed to first smoothScrollToPosition(0) to top-most position, then call submitList(it) and finally call scrollToPosition(0) but I can't achieve that (it is doing so fast, simultaneously, that it's layering each other). Maybe I should use coroutines? Don't know...
How am I supposed to add proper delay? Maybe I am doing something wrong because i read that some programmers had this autoscroll when added item.
Code sample
Adapter
class ExercisesListAdapter :
ListAdapter<Exercise, ExercisesListAdapter.ExerciseItemViewHolder>(ExercisesListDiffUtil()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ExerciseItemViewHolder {
val inflater = LayoutInflater.from(parent.context)
val binding: ItemRecyclerviewExerciseBinding =
DataBindingUtil.inflate(inflater, R.layout.item_recyclerview_exercise, parent, false)
return ExerciseItemViewHolder(binding)
}
override fun onBindViewHolder(holder: ExerciseItemViewHolder, position: Int) {
val currentExercise = getItem(position)
holder.bind(currentExercise)
}
override fun getItemId(position: Int): Long {
return getItem(position).id
}
// Item ViewHolder class
class ExerciseItemViewHolder(private val binding: ItemRecyclerviewExerciseBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(itemExercise: Exercise) {
binding.textCardExerciseName.text = itemExercise.name
}
}
}
DiffUtil
class ExercisesListDiffUtil: DiffUtil.ItemCallback<Exercise>() {
override fun areItemsTheSame(oldItem: Exercise, newItem: Exercise): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Exercise, newItem: Exercise): Boolean {
return oldItem == newItem
}
}
ViewModel
class CreateWorkoutViewModel(private val repository: WorkoutRepository) : ViewModel() {
private var exerciseId = 0L
private var exerciseList = mutableListOf<Exercise>()
val exerciseName = MutableLiveData<String?>()
private val _exerciseListLiveData = MutableLiveData<List<Exercise>>()
val exerciseListLiveData: LiveData<List<Exercise>>
get() = _exerciseListLiveData
fun onAddExercise() {
if (canValidateExerciseName())
addExerciseToList()
}
fun onAddWorkout() {
exerciseList.removeAt(2)
_exerciseListLiveData.value = exerciseList.toList()
}
private fun canValidateExerciseName(): Boolean {
return !exerciseName.value.isNullOrBlank()
}
private fun addExerciseToList() {
exerciseList.add(0, Exercise(exerciseId++, exerciseName.value!!))
_exerciseListLiveData.value = exerciseList.toList()
}
}
Fragment
class CreateWorkoutFragment : Fragment() {
lateinit var binding: FragmentCreateWorkoutBinding
lateinit var viewModel: CreateWorkoutViewModel
lateinit var recyclerView: RecyclerView
lateinit var adapter: ExercisesListAdapter
lateinit var layoutManager: LinearLayoutManager
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding =
DataBindingUtil.inflate(inflater, R.layout.fragment_create_workout, container, false)
setViewModel()
setRecyclerView()
// Observers:
// Update RecyclerView list on change
viewModel.exerciseListLiveData.observe(viewLifecycleOwner, {
adapter.submitList(it) {
layoutManager.smoothScrollToPosition(recyclerView, RecyclerView.State(), 0)
}
})
return binding.root
}
private fun setRecyclerView() {
recyclerView = binding.recyclerviewExercises
setLayoutManager()
setAdapter()
}
private fun setLayoutManager() {
layoutManager = LinearLayoutManager(context)
recyclerView.layoutManager = layoutManager
}
private fun setAdapter() {
adapter = ExercisesListAdapter()
adapter.setHasStableIds(true)
recyclerView.adapter = adapter
}
private fun setViewModel() {
val dao = WorkoutDatabase.getInstance(requireContext()).workoutDAO
val repository = WorkoutRepository(dao)
val factory = CreateWorkoutViewModelFactory(repository)
viewModel = ViewModelProvider(this, factory).get(CreateWorkoutViewModel::class.java)
binding.viewModel = viewModel
binding.lifecycleOwner = this
}
}
EDIT
I got it working but it's not 'elegant' way and insert animation is canceled through process :/
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
if(layoutManager.findFirstCompletelyVisibleItemPosition() == 0)
layoutManager.scrollToPosition(0)
else {
recyclerView.clearAnimation()
layoutManager.smoothScrollToPosition(recyclerView, RecyclerView.State(), 0)
}
}
})
I am new to Firebase and RecyclerViews and I am trying to get a list of ingredients from my Firebase Database and I want to create checkboxes for every item I retrieve from the database. I got as far as creating a RecyclerView and adapter for my Firebase Query but binding lists from the query doesn't seem to be covered anywhere I could find.
Please find below the code for putting the data into the recycler view as well as the layout files being used for the recycler view.
Data being retrieved
that I want to display the original field of my object as checkboxes
ShoppingListFragment.kt
class ShoppingListFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//Enable Firestore logging
FirebaseFirestore.setLoggingEnabled(true)
//Firestore
firestore = Firebase.firestore
// Get recipes that the user has liked up to ${LIMIT}
query = firestore.collection("recipes").whereArrayContains(
"plannedBy",
Firebase.auth.uid.toString()
)
.orderBy("name", Query.Direction.ASCENDING)
.limit(LIMIT.toLong())
// Init the adapter to hold the recipe objects.
adapter = object : ShoppingListAdapter(query) {
override fun onDataChanged() {
if (itemCount == 0) {
shoppingListRecycler.visibility = View.GONE
viewEmpty.visibility = View.VISIBLE
} else {
shoppingListRecycler.visibility = View.VISIBLE
viewEmpty.visibility = View.GONE
}
}
override fun onError(e: FirebaseFirestoreException) {
// Show a snackbar on errors
view?.let {
Snackbar.make(
it,
"Error: check logs for info.", Snackbar.LENGTH_LONG
).show()
}
}
}
...
}
...
}
ShoppingListAdapter.kt
open class ShoppingListAdapter(query: Query) :
FirestoreAdapter<ShoppingListViewHolder>(query) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShoppingListViewHolder {
return ShoppingListViewHolder(
ItemShoppingListBinding.inflate(
LayoutInflater.from(parent.context), parent, false))
}
override fun onBindViewHolder(holder: ShoppingListViewHolder, position: Int) {
holder.bind(getSnapshot(position))
}
}
ShoppingListViewHolder.kt
class ShoppingListViewHolder(val binding: ItemShoppingListBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(snapshot: DocumentSnapshot) {
val recipe = snapshot.toObject<Recipe>() ?: return
binding.listTitle.text = recipe.name
if(recipe.ingredients.size > 1) {
binding.shoppingListItem.text = recipe.ingredients[0].original
for(i in 1 until recipe.ingredients.size) {
val checkBox = CheckBox() //Not sure what to put here as the context for my recyclerview List Item
checkBox.text = recipe.ingredients[i].original
checkBox.layoutParams = LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
binding.shoppingListContainer.addView(checkBox)
}
} else {
binding.shoppingListItem.text = recipe.ingredients[0].original
}
}
}
I have tried passing a context parameter through ShoppingListViewHolder.kt and in turn adding that parameter to the adapter and so forth like so.
class ShoppingListViewHolder(val binding: ItemShoppingListBinding, val context: Context) : RecyclerView.ViewHolder(binding.root) {
fun bind(snapshot: DocumentSnapshot) {
val recipe = snapshot.toObject<Recipe>() ?: return
binding.listTitle.text = recipe.name
if(recipe.ingredients.size > 1) {
binding.shoppingListItem.text = recipe.ingredients[0].original
for(i in 1 until recipe.ingredients.size) {
val checkBox = CheckBox(context)
...
}
ShoppingListFragment.kt
// Init the adapter to hold the recipe objects.
adapter = object : ShoppingListAdapter(query, requireContext()) {
override fun onDataChanged() {
if (itemCount == 0) {
shoppingListRecycler.visibility = View.GONE
viewEmpty.visibility = View.VISIBLE
} else {
shoppingListRecycler.visibility = View.VISIBLE
viewEmpty.visibility = View.GONE
}
}
override fun onError(e: FirebaseFirestoreException) {
// Show a snackbar on errors
view?.let {
Snackbar.make(
it,
"Error: check logs for info.", Snackbar.LENGTH_LONG
).show()
}
}
}
But all that did was create a huge amount of white space between entries. After some debugging, it looks like passing the context from the fragment gave it the MainActivity context. I'm not too sure where to go from here and any help would be appreciated. Thank you!
you can use binding.root.context except passing context
My vertical RecyclerView (looking like a simple list) in Kotlin scrolls neatly to the next element when I press a button. 👍🏻
However when the next element is off screen (for example because in the meantime the user scrolled to a different position with a gesture) the problem is that this doesn't work anymore. Instead, it automatically scrolls all the way to the bottom of the RecyclerView.
Any idea how to fix that? I'd appreciate it!
Thanks in advance for your efforts.
I'm overriding SmoothScrollLinearLayoutManager:
class SmoothScrollLinearLayoutManager(private val mContext: Context, orientation: Int, reverseLayout: Boolean) : LinearLayoutManager(mContext, orientation, reverseLayout) {
override fun smoothScrollToPosition(recyclerView: RecyclerView, state: RecyclerView.State?,
position: Int) {
val smoothScroller = object : TopSnappedSmoothScroller(recyclerView.context) {
//This controls the direction in which smoothScroll looks for your view
override fun computeScrollVectorForPosition(targetPosition: Int): PointF {
return PointF(0f, 1f)
}
//This returns the milliseconds it takes to scroll one pixel.
protected override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float {
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi
}
}
smoothScroller.targetPosition = position
Log.i("Target", smoothScroller.targetPosition.toString())
startSmoothScroll(smoothScroller)
}
private open inner class TopSnappedSmoothScroller(context: Context) : LinearSmoothScroller(context) {
override fun computeScrollVectorForPosition(targetPosition: Int): PointF? {
return this#SmoothScrollLinearLayoutManager
.computeScrollVectorForPosition(targetPosition)
}
override fun getVerticalSnapPreference(): Int {
return LinearSmoothScroller.SNAP_TO_START
}
}
private open inner class CenterSnappedSmoothScroller(context: Context) : LinearSmoothScroller(context) {
override fun computeScrollVectorForPosition(targetPosition: Int): PointF? {
return this#SmoothScrollLinearLayoutManager
.computeScrollVectorForPosition(targetPosition)
}
override fun getVerticalSnapPreference(): Int {
return LinearSmoothScroller.SNAP_TO_END
}
}
// Scrolling speed
companion object {
private val MILLISECONDS_PER_INCH = 110f
}
}
The button triggers this function to scroll to the next element in the list (RecyclerView):
private fun fastForwardTapped() {
// Update selected position in RecyclerView
selectedPosition += 1
recyclerView.smoothScrollToPosition(selectedPosition)
}
It had to do with how I overrode LinearLayoutManager.
I ended up using this solution:
https://stackoverflow.com/a/36784136/8400139
It works.
I am trying to add functionality of swipe to delete as well as to show bottom sheet pop-up if RecyclerView item is long pressed. I am using ItemTouchHelper.SimpleCallback for swipe to delete and ItemTouchListener for showing pop-up on long press of item.
Problem is that when I am swiping the item to delete its also detecting long press.
What I want is that it should ignore long press when item is being swiped.
I have ItemTouchHelper class which extends Simplecallback for swipe to delete. Following is the code to attach recyclerview for swipe to delete.
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT, this);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
Follwing is code to add listener for long click event.
recyclerView.addOnItemTouchListener(new NotesRecyclerTouchListener(getApplicationContext(), recyclerView, new NotesRecyclerTouchListener.ClickListener() {
#Override
public void onLongClick(View view, int position) {
Note note = notesList.get(position);
Toast.makeText(getApplicationContext(), note.getTitle() + " is log pressed!", Toast.LENGTH_SHORT).show();
View sheetView = MainActivity.this.getLayoutInflater().inflate(R.layout.view_bottom_sheet_dialog, null);
BottomSheetDialog dialog = new BottomSheetDialog(MainActivity.this);
dialog.setContentView(sheetView);
dialog.show();
}
}));
onSwiped will be called when item will be completely swiped. If you will start to swipe element but then move it back, the method will not be called. So you shouldn't use this method to mark the end of swiping.
You can use isCurrentlyActive from onChildDraw like this:
var swiping: Boolean = false
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)
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
swiping = isCurrentlyActive
}
}
It will be true when you move element and false after swipe or cancelation of swipe.
As #DavidVelasquez has suggested you should set up a flag when swipe begins and act depending on it's state in your onLongClick() But onSwiped() is not the way to go. Instead you should use ItemTouchHelper.SimpleCallback#onChildDraw() method to detect when the swipe beings and onSwiped() method to detect when it ends.
Eg.
override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int,isCurrentlyActive: Boolean) {
if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){
setupMyFlag()
}
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
clearMyFlag()
}
And then just check this flag in your onLongClick()