0
0
Android Kotlinmobile~20 mins

Pull-to-refresh in Android Kotlin - Mini App: Build & Ship

Choose your learning style9 modes available
Build: PullToRefreshScreen
A simple screen that shows a list of items and allows the user to refresh the list by pulling down from the top.
Target UI
-------------------------
| PullToRefreshScreen    |
-------------------------
| ↓ Pull down to refresh |
|-----------------------|
| Item 1                |
| Item 2                |
| Item 3                |
| Item 4                |
| Item 5                |
-------------------------
Use SwipeRefreshLayout to enable pull-to-refresh gesture
Display a vertical list of 5 static items labeled Item 1 to Item 5
When user pulls down, show a loading spinner for 2 seconds
After loading, update the list by appending ' - refreshed' to each item
Ensure the UI is simple and accessible
Starter Code
Android Kotlin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.LinearLayoutManager

class PullToRefreshScreen : AppCompatActivity() {
    private lateinit var swipeRefreshLayout: SwipeRefreshLayout
    private lateinit var recyclerView: RecyclerView
    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_pull_to_refresh)

        swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout)
        recyclerView = findViewById(R.id.recyclerView)

        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = ItemAdapter(items)

        // TODO: Add pull-to-refresh logic here
    }
}

// TODO: Create ItemAdapter class for RecyclerView
Task 1
Task 2
Task 3
Task 4
Task 5
Solution
Android Kotlin
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.appcompat.app.AppCompatActivity
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView

class PullToRefreshScreen : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener {
    private lateinit var swipeRefreshLayout: SwipeRefreshLayout
    private lateinit var recyclerView: RecyclerView
    private val items = mutableListOf("Item 1", "Item 2", "Item 3", "Item 4", "Item 5")
    private lateinit var adapter: ItemAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_pull_to_refresh)

        swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout)
        recyclerView = findViewById(R.id.recyclerView)

        recyclerView.layoutManager = LinearLayoutManager(this)
        adapter = ItemAdapter(items)
        recyclerView.adapter = adapter

        swipeRefreshLayout.setOnRefreshListener(this)
    }

    override fun onRefresh() {
        // Show loading spinner for 2 seconds
        Handler(Looper.getMainLooper()).postDelayed({
            for (i in items.indices) {
                items[i] = items[i].removeSuffix(" - refreshed") + " - refreshed"
            }
            adapter.notifyDataSetChanged()
            swipeRefreshLayout.isRefreshing = false
        }, 2000)
    }
}

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 SwipeRefreshLayout to enable the pull-to-refresh gesture. The activity implements SwipeRefreshLayout.OnRefreshListener to listen for the pull gesture.

When the user pulls down, onRefresh() is called. We simulate a 2-second loading delay using a Handler and postDelayed. After the delay, we update each item by appending " - refreshed" (removing duplicates if any), then notify the adapter to refresh the list UI.

The refreshing spinner is stopped by setting isRefreshing = false. The ItemAdapter is a simple RecyclerView adapter that shows each item in a text view.

This approach keeps the UI responsive and provides a familiar pull-to-refresh experience.

Final Result
Completed Screen
-------------------------
| PullToRefreshScreen    |
-------------------------
| ↓ Pull down to refresh |
|-----------------------|
| Item 1 - refreshed     |
| Item 2 - refreshed     |
| Item 3 - refreshed     |
| Item 4 - refreshed     |
| Item 5 - refreshed     |
-------------------------
User pulls down from top of list
A spinner appears at top indicating loading
After 2 seconds, spinner disappears
List items update to show ' - refreshed' appended
Stretch Goal
Add a button that resets the list items back to original labels without ' - refreshed'.
💡 Hint
Add a Button below the list. On click, reset the items list to original values and notify adapter.