Last updated Jan 09, 2022

SwipeRefreshLayout: Pull to Refresh with RecyclerView

In this android example tutorial, we will see how to refresh data using SwipeRefreshLayout widget with RecyclerView in Android using Kotlin.

Recyclerview: RecyclerView is a more advanced and adaptable version of the listview and gridview. It's a container for presenting large amounts of data sets in a way that allows them to be browsed quickly while limiting the number of views. It has the ability to reuse its views. 

SwipeRefreshLayout: SwipeRefreshLayout is a widget that implements the swipe-to-refresh user interface design pattern. Where the user employs the vertical swipe gesture to refresh the views' content.
It enables the user to manually refresh the programme. OnRefreshListener is a listener in the SwipeRefreshLayout class. SwipeRefreshLayout should be implemented by classes that want to use this listener. The interface OnRefreshListener.

Implementation of SwipeRefreshLayout with Recyclerview:

Step 1. Create a new Project in android studio.

Go to File > New > New Project > Empty Activity > Next > Enter Name > Select Language Kotlin > Finish.


Step 2. Add the RecyclerView and SwipeRefreshLayout dependency to build.gradle(app).

implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'

 

Step 3. Go to activity_main.xml file and add the following xml code:

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/swipeRefreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

 

Step 4. Create a new layout resource file and add the following code 

app > res > layout > new > layout resource file > enter name (layout_items) > ok


Code:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:orientation="horizontal"
    android:padding="10dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:scaleType="fitXY"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:paddingStart="10dp"
        android:text="Android " />

</LinearLayout>

 

Step 5. Create a new Kotlin class for model 

app > java > package name > right-click > New > Kotlin class/file (RecyclerModel > enter name > OK


Code:
This file will hold the information of every item which you want to show in your RecyclerView.

class RecyclerModel(val image : Int, val text: String) {

}
 

 

Step 6. Create a adapter class

app > java > package name > right-click > New > Kotlin class/file (RecyclerAdapter) > enter name > ok

 

This class contains some important functions to work with the RecyclerView these are as follows:

 

onCreateViewHolder(): This function sets the views to display the items.
onBindViewHolder(): This function is used to bind the list items to our widgets such as TextView, ImageView, etc.
getItemCount(): It returns the count of items present in the list.

 

Code:

class RecyclerAdapter(private val dataList: List) : RecyclerView.Adapter() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.layout_items, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
        val recyclerModel = dataList[position]

        // Image set to the imageview widget
        holder.imageView.setImageResource(recyclerModel.image)

        // Text set to the textview widget
        holder.textView.text = recyclerModel.text
    }

    override fun getItemCount(): Int {
        return dataList.size
    }
    class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
        val imageView: ImageView = itemView.findViewById(R.id.imageView)
        val textView: TextView = itemView.findViewById(R.id.textView)
    }

}

 

Step 7. Go to MainActivity.kt file and add the following code

Initialize the recyclerView and SwipeRefreshLayout widget below setContentView(R.layout.activity_main).

   val recyclerview = findViewById(R.id.recyclerView)
   val swipe = findViewById(R.id.swipeRefreshLayout)


        // Used for vertical linearlayout view
        recyclerview.layoutManager = LinearLayoutManager(this)

        // ArrayList of class RecyclerModel
        val data = ArrayList()

        // This loop will create 12 Views containing
        // the image with the count of view
        for (i in (1..12)) {
            // radom() is a function to get random no. between two values
            val no = (1..12).random()
            
            data.add(RecyclerModel(R.drawable.ic_launcher_background, "Android " + no))
        }

        // Used for refresh the data
        swipe.setOnRefreshListener {
            swipe.isRefreshing = false
            val adapter = RecyclerAdapter(data)
            recyclerview.adapter = adapter
            Toast.makeText(this, "Data Refreshed", Toast.LENGTH_SHORT).show()
        }
        // This will pass the ArrayList to our Adapter
        val adapter = RecyclerAdapter(data)

        // Setting the Adapter with the recyclerview
        recyclerview.adapter = adapter

 

Step 8. Now run the app in your emulator, and get the following output.

OUTPUT:
 

Android Swipe to Refresh Recyclerview data


When we pull to refresh:

Android Swipe to Refresh Recyclerview data 2

When data is refreshed:

Android Swipe to Refresh Recyclerview data 3


 

Complete source code of Pull to refresh with RecyclerView with Example:

activity_main.xml file

<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/swipeRefreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

 

MainActivity.kt file

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout


class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val recyclerview = findViewById(R.id.recyclerView)
        val swipe = findViewById(R.id.swipeRefreshLayout)

        // Used for vertical linearlayout view
        recyclerview.layoutManager = LinearLayoutManager(this)

        // ArrayList of class RecyclerModel
        val data = ArrayList()

        // This loop will create 12 Views containing
        // the image with the count of view
        for (i in (1..12)) {
            val no = (1..12).random()
            data.add(RecyclerModel(R.drawable.ic_launcher_background, "Android " + no))
        }

        swipe.setOnRefreshListener {
            swipe.isRefreshing = false
            val adapter = RecyclerAdapter(data)
            recyclerview.adapter = adapter
            Toast.makeText(this, "Data Refreshed", Toast.LENGTH_SHORT).show()
        }
        // This will pass the ArrayList to our Adapter
        val adapter = RecyclerAdapter(data)

        // Setting the Adapter with the recyclerview
        recyclerview.adapter = adapter

    }
}

 

layout_items.xml file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:orientation="horizontal"
    android:padding="10dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:scaleType="fitXY"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:paddingStart="10dp"
        android:text="Android " />

</LinearLayout>

 

RecyclerModel.kt file

class RecyclerModel(val image : Int, val text: String) {

}

 

RecyclerAdapter.kt file

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView


class RecyclerAdapter(private val dataList: List) : RecyclerView.Adapter() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.layout_items, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
        val recyclerModel = dataList[position]

        // Image set to the imageview widget
        holder.imageView.setImageResource(recyclerModel.image)

        // Text set to the textview widget
        holder.textView.text = recyclerModel.text
    }

    override fun getItemCount(): Int {
        return dataList.size
    }
    class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
        val imageView: ImageView = itemView.findViewById(R.id.imageView)
        val textView: TextView = itemView.findViewById(R.id.textView)
    }

}

 

build.gradle(app) file

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdk 31

    defaultConfig {
        applicationId "com.nishajain.swipeRefresh"
        minSdk 21
        targetSdk 31
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.4.0'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
}

 

Conclusion: In this article we have covered how to implement pull to refresh with recyclerview using SwipeRefreshLayout widget in Android USing Kotlin.

 

Download Source code