Bird
Raised Fist0
Android Kotlinmobile~20 mins

Swipe to dismiss in Android Kotlin - Mini App: Build & Ship

Choose your learning style10 modes available
Build: SwipeToDismissList
A screen that shows a list of items. You can swipe an item left or right to remove it from the list.
Target UI
Swipe to dismiss list:
-----------------------
| Item 1             |
| Item 2             |
| Item 3             |
| Item 4             |
| Item 5             |
-----------------------
Display a vertical list of text items
Allow user to swipe left or right on an item to remove it
Show a Snackbar with Undo option after dismissal
Undo restores the removed item to the list
Starter Code
Android Kotlin
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
    }
}
Task 1
Task 2
Task 3
Task 4
Solution
Android Kotlin
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.

Final Result
Completed Screen
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]
Swipe an item left or right to remove it from the list
Snackbar appears at bottom with Undo button
Tap Undo to restore the removed item in the same position
Stretch Goal
Add a confirmation dialog before removing the item after swipe
💡 Hint
Use AlertDialog in onSwiped to ask user to confirm removal before deleting the item

Practice

(1/5)
1.

What is the main purpose of implementing onSwiped in ItemTouchHelper.SimpleCallback when using swipe to dismiss?

easy
A. To change the background color of the list item
B. To add a new item to the list
C. To disable swipe gestures on the list
D. To remove the swiped item from the data and update the UI

Solution

  1. Step 1: Understand the role of onSwiped

    This method is called when a user swipes an item. It is used to handle what happens after the swipe gesture.
  2. Step 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.
  3. Final Answer:

    To remove the swiped item from the data and update the UI -> Option D
  4. Quick Check:

    onSwiped removes item [OK]
Hint: Remember: swipe means remove item and refresh list [OK]
Common Mistakes:
  • Trying to add items in onSwiped
  • Ignoring data update after swipe
  • Using onSwiped to change colors only
2.

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(?, ?) {}
easy
A. 0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
B. ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
C. ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT, 0
D. ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0

Solution

  1. Step 1: Understand SimpleCallback constructor parameters

    The first parameter is for drag directions, the second for swipe directions.
  2. 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.
  3. Final Answer:

    0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT -> Option A
  4. Quick Check:

    Drag=0, Swipe=LEFT|RIGHT [OK]
Hint: Drag=0 disables drag; swipe=LEFT|RIGHT enables swipe [OK]
Common Mistakes:
  • Swapping drag and swipe parameters
  • Using drag directions when only swipe needed
  • Setting swipe to 0 disables swipe
3.

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?

medium
A. The item remains but the UI flashes
B. The item is removed from the list and the UI updates to reflect the change
C. The app crashes due to invalid position
D. Nothing happens because notifyItemRemoved is missing

Solution

  1. Step 1: Remove item from data list

    The code removes the item at the swiped position from the data list.
  2. Step 2: Notify adapter about removal

    Calling notifyItemRemoved updates the UI to remove the item visually.
  3. Final Answer:

    The item is removed from the list and the UI updates to reflect the change -> Option B
  4. Quick Check:

    Remove item + notify adapter = UI updates [OK]
Hint: Remove data then notify adapter to update UI [OK]
Common Mistakes:
  • Not removing item from data list
  • Forgetting to notify adapter
  • Using wrong adapter position
4.

What is wrong with this onSwiped implementation?

override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
    adapter.notifyItemRemoved(viewHolder.adapterPosition)
    items.removeAt(viewHolder.adapterPosition)
}
medium
A. The adapter position is not valid inside onSwiped
B. The method is missing a call to super.onSwiped
C. Calling notifyItemRemoved before removing item causes UI inconsistency
D. Nothing is wrong; this code works fine

Solution

  1. Step 1: Check order of operations

    notifyItemRemoved should be called after removing the item from the data list.
  2. Step 2: Understand impact of wrong order

    Calling notifyItemRemoved first causes the adapter to update UI before data changes, leading to inconsistency or crash.
  3. Final Answer:

    Calling notifyItemRemoved before removing item causes UI inconsistency -> Option C
  4. Quick Check:

    Remove data first, then notify adapter [OK]
Hint: Always update data before notifying adapter [OK]
Common Mistakes:
  • Not removing item before notify
  • Calling super.onSwiped unnecessarily
  • Using wrong adapter position
5.

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)
hard
A. This code allows swipe only to the right and removes the item correctly
B. This code allows swipe both left and right
C. This code will crash because onMove is not implemented properly
D. This code does not remove the item from the list

Solution

  1. Step 1: Check swipe directions in SimpleCallback

    Swipe is set to ItemTouchHelper.RIGHT only, so only right swipe is allowed.
  2. Step 2: Verify onSwiped removes item and notifies adapter

    onSwiped removes the item at adapterPosition and calls notifyItemRemoved correctly.
  3. Step 3: Confirm onMove returns false

    Returning false disables drag, which is intended here.
  4. Final Answer:

    This code allows swipe only to the right and removes the item correctly -> Option A
  5. Quick Check:

    Swipe=RIGHT only + remove item + notify adapter [OK]
Hint: Set swipe directions and remove item in onSwiped [OK]
Common Mistakes:
  • Setting swipe to LEFT or both directions
  • Not removing item from data list
  • Returning true in onMove causing drag
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard