How to add pull to refresh to a RecyclerView in Android Kotlin
How to add pull to refresh to a RecyclerView in Android Kotlin:
In this post, we will learn how to add a pull to refresh to a RecyclerView in Android. We will use the same project we are using in the RecyclerView tutorial series. This post will focus only on pull to refresh and I will not move into other details of the project.
YouTube video:
You can also watch the step by step video on YouTube:
Step 1: Add the SwipeRefreshLayout dependency:
You need to add a dependency for the swiperefreshlayout in your project. Add the following dependency in your app level build.gradle
file:
dependencies {// other dependencies+ implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"}
Sync your project.
Step 2: Add the SwipeRefreshLayout in the layout file:
We need to add the SwipeRefreshLayout in the layout xml file. This component should wrap the RecyclerView component. In our example program, we will wrap it as below:
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity">+ <androidx.swiperefreshlayout.widget.SwipeRefreshLayout+ android:layout_width="match_parent"+ android:layout_height="match_parent"+ android:id="@+id/swipeRefresh"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginStart="1dp"android:layout_marginLeft="1dp"android:layout_marginTop="25dp"android:layout_marginEnd="1dp"android:layout_marginRight="1dp"android:layout_marginBottom="1dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" />+ </androidx.swiperefreshlayout.widget.SwipeRefreshLayout></androidx.constraintlayout.widget.ConstraintLayout>
We wrapped the RecyclerView with a SwipeRefreshLayout component. This is the only change required in the layout file.
Update your Activity:
We have to update the activity file to get a reference of the SwipeRefreshLayout layout. We can add a listener on it.
The MainActivity file of the current project is updated as below:
package com.example.myapplicationimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport androidx.recyclerview.widget.LinearLayoutManagerimport androidx.recyclerview.widget.RecyclerView+ import androidx.swiperefreshlayout.widget.SwipeRefreshLayoutimport com.example.myapplication.models.Propertyimport com.example.myapplication.network.Apiimport retrofit2.Callimport retrofit2.Callbackimport retrofit2.Responseclass MainActivity : AppCompatActivity() {lateinit var data: MutableList<Property>private lateinit var recyclerView: RecyclerViewprivate lateinit var manager: RecyclerView.LayoutManagerprivate lateinit var myAdapter: MyAdapterprivate lateinit var swipeRefresh: SwipeRefreshLayoutoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)manager = LinearLayoutManager(this)+ swipeRefresh = findViewById(R.id.swipeRefresh)+ swipeRefresh.setOnRefreshListener {+ getAllData()+ }getAllData()}fun getAllData(){Api.retrofitService.getAllData().enqueue(object: Callback<List<Property>>{override fun onResponse(call: Call<List<Property>>,response: Response<List<Property>>) {+ if(swipeRefresh.isRefreshing){+ swipeRefresh.isRefreshing = false+ }if(response.isSuccessful){recyclerView = findViewById<RecyclerView>(R.id.recycler_view).apply{data = response.body() as MutableList<Property>myAdapter = MyAdapter(data){index -> deleteItem(index)}layoutManager = manageradapter = myAdapter}}}override fun onFailure(call: Call<List<Property>>, t: Throwable) {t.printStackTrace()}})}fun deleteItem(index: Int){if(::data.isInitialized && ::myAdapter.isInitialized){data.removeAt(index)myAdapter.setItems(data)}}}
- Import the SwipeRefreshLayout component.
- Get the reference and assign it to the swipeRefresh variable.
- Add one setOnRefreshListener. It calls the getAllData method to fetch the data.
- After the data is fetched, it checks if it is still refreshing or not with the isRefreshing property. It assigns it as false if it is true.
Github:
The code is available on Github. Please use the tut-swiperefresh tag to get the code explained on this tutorial.
git clone https://github.com/AppDevAssist/recyclerview-kotlin && git checkout tags/tut-swiperefresh