Android

RecyclerView Pull To Refresh Example

Pinterest LinkedIn Tumblr

For getting the latest feeds, the SwipeRefreshLayout widget uses. You have seen it on different popular apps like Facebook, Twitter, or Linkedin. When you swipe down from the top position the latest feeds start loading if have.

SwipeRefreshLayout is a ViewGroup that can hold one widget that can be either a ScrollView or any AdapterView such as RecyclerView.

Jump to section

Demo

SwipeRefreshLayout Demo

Step-1 (Create a new project)

Open the Android Studio and create a new project and select a blank template.

Step- 2 (Add dependencies)

Go to the build.gradle.xml file and add the below dependencies to it.

dependencies {

    implementation 'androidx.appcompat:appcompat:1.3.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

Step-3 (Project Resources)

1- Go to the colors.xml file and add below code

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>

    <!-- view colors -->
    <color name="red_view">#C70E0E</color>
    <color name="green_view">#015F25</color>
    <color name="blue_view">#1126CB</color>
    <color name="purple_view">#7109A8</color>
</resources>

2- Go to the strings.xml file and add below strings

<resources>
    <string name="app_name">RecyclerViewPullToRefreshExample</string>
    <string name="demo_title">RecyclerView Pull To Refresh</string>
    <string name="random_title">Random Title</string>
    <string name="random_description">The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested.</string>
</resources>

3- In the design, four random drawable circles will use as background. These circles will display as the background of numbering.

Navigate to the app > res > drawable > Right-click on it > New > Drawable Resource File and create four files.

Blue Color Circle Drawable Resource File

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <solid android:color="@color/blue_view"/>
</shape>

Green Color Drawable Resource File

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <solid android:color="@color/green_view"/>
</shape>

Purple Color Drawable Resource File

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <solid android:color="@color/purple_view"/>
</shape>

Red Color Drawable Resource File

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <solid android:color="@color/red_view"/>
</shape>

Step-4 (Design a layout for RecyclerView Item)

Navigate to the app > res > layout > Right-click on it > New > Layout Resource File and renamed it adapter_demo.xml. Add below code to it.

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    app:cardUseCompatPadding="true"
    android:layout_height="100dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <View
            android:id="@+id/viewBg"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:background="@drawable/view_with_red_color"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tvNumber"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1"
            android:textColor="@color/white"
            android:textSize="24sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="@+id/viewBg"
            app:layout_constraintEnd_toEndOf="@+id/viewBg"
            app:layout_constraintStart_toStartOf="@+id/viewBg"
            app:layout_constraintTop_toTopOf="@+id/viewBg" />

        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="0dp"
            android:layout_marginStart="5dp"
            android:layout_height="wrap_content"
            android:text="@string/random_title"
            android:textColor="@color/black"
            android:textSize="20sp"
            app:layout_constraintVertical_chainStyle="packed"
            app:layout_constraintBottom_toTopOf="@+id/tvDescription"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/viewBg"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tvDescription"
            android:layout_width="0dp"
            android:layout_marginStart="5dp"
            android:layout_height="wrap_content"
            android:text="@string/random_description"
            android:textColor="@color/black"
            android:textSize="16sp"
            android:lines="3"
            android:ellipsize="end"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/viewBg"
            app:layout_constraintTop_toBottomOf="@+id/tvTitle" />


    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

Step-5 (Working with modal class)

To display the list, we will use a modal class that will hold the demo data. You can customize according to your requirments. Create a Java class and renamed it with RandomM.java. RandomM.java has two properties title and description. Add below code in RandomM.java file

package com.example.recyclerviewpulltorefreshexample;

public class RandomM {
    private String title;
    private String description;

    public RandomM(String title, String description, int type) {
        this.title = title;
        this.description = description;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

Step-6 (Working with RecyclerView Adapter)

In my RecyclerView tutorials, I have written, how to create a RecyclerView Adapter Java file? If you have no idea, Read here about RecyclerView Adapter.

Navigate the java folder and create a new Java class and renamed it AdapterRandom.java. Add the below code to it.

package com.example.recyclerviewpulltorefreshexample;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class AdapterRandom extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<RandomM> randomMList;
    private int[] bgDrawables = {R.drawable.view_with_red_color, R.drawable.view_with_blue_color, R.drawable.view_with_purple_color, R.drawable.view_with_green_color};
    private Context _context;


    AdapterRandom(List<RandomM> randomMList) {
        this.randomMList = randomMList;
    }

    private class RandomViewHolder extends RecyclerView.ViewHolder {
        private TextView tvTitle;
        private TextView tvNumber;
        private TextView tvDescription;
        private View viewBg;

        public RandomViewHolder(View itemView) {
            super(itemView);
            tvTitle = itemView.findViewById(R.id.tvTitle);
            tvNumber = itemView.findViewById(R.id.tvNumber);
            tvDescription = itemView.findViewById(R.id.tvDescription);
            viewBg = itemView.findViewById(R.id.viewBg);
        }
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        _context = parent.getContext();
        View v1 = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_demo, parent, false);
        return new RandomViewHolder(v1);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (holder.getItemViewType() == 0) {
            RandomViewHolder randomViewHolder = (RandomViewHolder) holder;
            RandomM celebrityModal = randomMList.get(position);
            randomViewHolder.tvTitle.setText(celebrityModal.getTitle());
            randomViewHolder.tvDescription.setText(celebrityModal.getDescription());
            randomViewHolder.viewBg.setBackgroundResource(bgDrawables[position % 4]);
            randomViewHolder.tvNumber.setText((position + 1) + "");
        }
    }

    @Override
    public int getItemCount() {
        return randomMList.size();
    }   
}

Step-7 (Design a activity_main.xml file)

In this file, we will add the SwipeRefreshLayout widget. RecyclerView will be a child of the SwipeRefreshLayout widget. Go to the activity_main.xml file and add the below code to it.

<?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">

    <TextView
        android:id="@+id/tvDemoTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="@string/demo_title"
        android:textColor="@color/black"
        android:textSize="26sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefresh"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_margin="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvDemoTitle">

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

</androidx.constraintlayout.widget.ConstraintLayout>

Step-8 (Working with MainActivity.java)

  • initComponents() will initialize the components being used.
  • prepareDummyData() method will set the dummy data to the list.
  • initSwipeRefreshLister() will set the listener to the object of SwipeRefreshLayout.
  • When user swipe down from the top position then onLoadMore() method will call and load the more data in 2.5 second. Keep in mind, in the code we’re using ovverride onRefresh() method, which is replaced by the lambda function. Below is the code for MainActivity.java. Comments are added for understand the code.
package com.example.recyclerviewpulltorefreshexample;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import android.os.Bundle;
import android.os.Handler;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private RecyclerView rcvListing;
    private SwipeRefreshLayout swipeRefresh;
    private AdapterRandom adapterRandom;
    private List<RandomM> randomMList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initComponents();
        prepareDummyData();
        initSwipeRefreshListener();
    }

    /**
     * initialize the components
     */
    private void initComponents() {
        randomMList = new ArrayList<>();
        adapterRandom = new AdapterRandom(randomMList);
        rcvListing = findViewById(R.id.rcvListing);
        swipeRefresh = findViewById(R.id.swipeRefresh);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
        rcvListing.setLayoutManager(linearLayoutManager);
        rcvListing.setAdapter(adapterRandom);
    }

    /**
     * setup the dummy data to random list and recall the adapter
     */
    private void prepareDummyData() {
        for (int i = 0; i < 10; i++) {
            randomMList.add(new RandomM(getString(R.string.random_title), getString(R.string.random_description), 0));
        }
        adapterRandom.notifyDataSetChanged();
    }

    /**
     * init SwipeRefreshLister using lambda method
     */
    private void initSwipeRefreshListener() {
        swipeRefresh.setOnRefreshListener(() -> loadMoreData()); // lambda function
    }

    /**
     * when swipe listener will call then this method will load more 10 item and will set on the top of  list and recall the adapter method
     */
    private void loadMoreData() {
        Handler handler = new Handler();
        handler.postDelayed(() -> {
            List<RandomM> refreshLoadingDataList = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                refreshLoadingDataList.add(new RandomM(getString(R.string.random_title), getString(R.string.random_description), 0));
            }
            randomMList.addAll(refreshLoadingDataList);
            adapterRandom.notifyDataSetChanged();
            swipeRefresh.setRefreshing(false);
        }, 2500);

    }
}

Now just run the code and enjoy, if you face any issue related to this tutorial, you can ask via comments.

Step-9 (Download Project Resources)

Thanks for reading the tutorial. Subscribe to my YouTube channel. Like and Share my Facebook page with your friends.

Write A Comment