Swipe to dismiss list: ----------------------- | Item 1 | | Item 2 | | Item 3 | | Item 4 | | Item 5 | -----------------------
Swipe to dismiss in Android Kotlin - Mini App: Build & Ship
package com.example.swipetodismiss import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.snackbar.Snackbar class SwipeToDismissList : AppCompatActivity() { private lateinit var recyclerView: RecyclerView private lateinit var adapter: ItemAdapter private val items = mutableListOf("Item 1", "Item 2", "Item 3", "Item 4", "Item 5") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_swipe_to_dismiss_list) recyclerView = findViewById(R.id.recyclerView) recyclerView.layoutManager = LinearLayoutManager(this) adapter = ItemAdapter(items) recyclerView.adapter = adapter // TODO: Add swipe to dismiss functionality here } }
package com.example.swipetodismiss import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.snackbar.Snackbar class SwipeToDismissList : AppCompatActivity() { private lateinit var recyclerView: RecyclerView private lateinit var adapter: ItemAdapter private val items = mutableListOf("Item 1", "Item 2", "Item 3", "Item 4", "Item 5") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_swipe_to_dismiss_list) recyclerView = findViewById(R.id.recyclerView) recyclerView.layoutManager = LinearLayoutManager(this) adapter = ItemAdapter(items) recyclerView.adapter = adapter val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) { override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { return false } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { val position = viewHolder.adapterPosition val removedItem = items[position] items.removeAt(position) adapter.notifyItemRemoved(position) Snackbar.make(recyclerView, "$removedItem removed", Snackbar.LENGTH_LONG) .setAction("Undo") { items.add(position, removedItem) adapter.notifyItemInserted(position) }.show() } } val itemTouchHelper = ItemTouchHelper(itemTouchHelperCallback) itemTouchHelper.attachToRecyclerView(recyclerView) } } // Adapter class for RecyclerView import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.RecyclerView class ItemAdapter(private val items: List<String>) : RecyclerView.Adapter<ItemAdapter.ViewHolder>() { class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val textView: TextView = itemView.findViewById(android.R.id.text1) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) .inflate(android.R.layout.simple_list_item_1, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.textView.text = items[position] } override fun getItemCount(): Int = items.size }
This solution uses ItemTouchHelper.SimpleCallback to detect swipe gestures on the RecyclerView items. When the user swipes left or right, the onSwiped method is called.
Inside onSwiped, the item is removed from the list and the adapter is notified to update the UI. Then a Snackbar appears with an Undo button.
If the user taps Undo, the removed item is added back to the list at the same position and the adapter updates the UI again.
This approach gives a smooth swipe-to-dismiss experience with a chance to undo accidental removals.
Swipe to dismiss list: ----------------------- | Item 1 | | Item 2 | | Item 3 | | Item 4 | | Item 5 | ----------------------- User swipes Item 3 to the left: ----------------------- | Item 1 | | Item 2 | | Item 4 | | Item 5 | ----------------------- [Snackbar: "Item 3 removed" Undo]
Practice
What is the main purpose of implementing onSwiped in ItemTouchHelper.SimpleCallback when using swipe to dismiss?
Solution
Step 1: Understand the role of
This method is called when a user swipes an item. It is used to handle what happens after the swipe gesture.onSwipedStep 2: Identify the correct action after swipe
The typical action is to remove the swiped item from the data source and notify the adapter to update the UI.Final Answer:
To remove the swiped item from the data and update the UI -> Option DQuick Check:
onSwipedremoves item [OK]
- Trying to add items in onSwiped
- Ignoring data update after swipe
- Using onSwiped to change colors only
Which of the following is the correct way to create a SimpleCallback for swipe to dismiss only (no drag) in Kotlin?
val callback = object : ItemTouchHelper.SimpleCallback(?, ?) {}Solution
Step 1: Understand SimpleCallback constructor parameters
The first parameter is for drag directions, the second for swipe directions.Step 2: Set drag to 0 and swipe to left or right
For swipe to dismiss only, drag should be 0 and swipe should allow left or right.Final Answer:
0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT -> Option AQuick Check:
Drag=0, Swipe=LEFT|RIGHT [OK]
- Swapping drag and swipe parameters
- Using drag directions when only swipe needed
- Setting swipe to 0 disables swipe
Given this code snippet inside onSwiped:
val position = viewHolder.adapterPosition items.removeAt(position) adapter.notifyItemRemoved(position)
What will happen when the user swipes an item?
Solution
Step 1: Remove item from data list
The code removes the item at the swiped position from the data list.Step 2: Notify adapter about removal
Calling notifyItemRemoved updates the UI to remove the item visually.Final Answer:
The item is removed from the list and the UI updates to reflect the change -> Option BQuick Check:
Remove item + notify adapter = UI updates [OK]
- Not removing item from data list
- Forgetting to notify adapter
- Using wrong adapter position
What is wrong with this onSwiped implementation?
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
adapter.notifyItemRemoved(viewHolder.adapterPosition)
items.removeAt(viewHolder.adapterPosition)
}Solution
Step 1: Check order of operations
notifyItemRemoved should be called after removing the item from the data list.Step 2: Understand impact of wrong order
Calling notifyItemRemoved first causes the adapter to update UI before data changes, leading to inconsistency or crash.Final Answer:
Calling notifyItemRemoved before removing item causes UI inconsistency -> Option CQuick Check:
Remove data first, then notify adapter [OK]
- Not removing item before notify
- Calling super.onSwiped unnecessarily
- Using wrong adapter position
You want to implement swipe to dismiss in a RecyclerView but only allow swipe to the right. Which code snippet correctly sets up the SimpleCallback and handles the swipe?
val callback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
override fun onMove(...) = false
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val pos = viewHolder.adapterPosition
items.removeAt(pos)
adapter.notifyItemRemoved(pos)
}
}
ItemTouchHelper(callback).attachToRecyclerView(recyclerView)Solution
Step 1: Check swipe directions in SimpleCallback
Swipe is set to ItemTouchHelper.RIGHT only, so only right swipe is allowed.Step 2: Verify onSwiped removes item and notifies adapter
onSwiped removes the item at adapterPosition and calls notifyItemRemoved correctly.Step 3: Confirm onMove returns false
Returning false disables drag, which is intended here.Final Answer:
This code allows swipe only to the right and removes the item correctly -> Option AQuick Check:
Swipe=RIGHT only + remove item + notify adapter [OK]
- Setting swipe to LEFT or both directions
- Not removing item from data list
- Returning true in onMove causing drag
Ready to prove it?
Pass the test and this pattern moves unknown
