You might have noticed that lot of android apps like Twitter, Google+ provides an option to swipe / pull down to refresh it’s content. Whenever user swipes down from top, a loader will be shown and will disappear once the new content is loaded. In this tutorial we are going to learn how to provide the same option to your apps too.

Previously we used to implement a custom swipe view to detect the swipe down. But android made our day easier by introducing SwipeRefreshLayout in android.support.v4 to detect the vertical swipe on any view.

android-swipe-down-to-refresh-list-view-tutorial

1. Android SwipeRefreshLayout

Implementing SwipeRefreshLayout is very easy. Whenever you want to detect the swipe down on any view, just the wrap the view around SwipeRefreshLayout element. In our case, we are going to use it with ListView. And implement your activity class from SwipeRefreshLayout.OnRefreshListener. When user swipes down the view, onRefresh() method will be triggered. In you need to take appropriate action in that function like making an http call and fetch the latest data.

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <!-- place your view here -->

</android.support.v4.widget.SwipeRefreshLayout>

2. Example JSON

To demonstrate this tutorial, I am showing IMDB top 250 movies in a List View. For this I have created a json service which gives 20 movies in each request. You need to pass offset param to get the next set of results. Initially offset value should be 0, whenever the list is swiped down, we make an http call to get the next 20 movies and will update the ListView.

URL: https://api.androidhive.info/json/imdb_top_250.php?offset=0

3. Creating Android Project

1. In Android Studio, create a new project by navigating to File ⇒ New Project and fill all the required details. When it prompts to select a default activity, select Blank Activity and proceed.

2. Open build.gradle located under app folder and add volley library dependency. We are going to use volley to make HTTP calls to fetch the json.

com.mcxiaoke.volley:library-aar:1.0.0

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.1.0'
    compile 'com.mcxiaoke.volley:library-aar:1.0.0'
}

3. Open colors.xml under res ⇒ values and add below color resources. If you don’t find colors.xml, create a new file with the name. The color resources added below are used to set background color for movies rank in list view.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="movie_serial_bg">
        <item>#24c6d5</item>
        <item>#57dd86</item>
        <item>#ad7dcf</item>
        <item>#ff484d</item>
        <item>#fcba59</item>
        <item>#24c6d5</item>
    </string-array>
</resources>

3. Now under your project’s package, create three packages named app, activity and helper.

4. Under app package, create a class named MyApplication.java and add below code. This is a singleton Application class which initiates volley core objects on app launch.

package info.androidhive.swiperefresh.app;

import android.app.Application;
import android.text.TextUtils;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

/**
 * Created by Ravi on 13/05/15.
 */

public class MyApplication extends Application {

    public static final String TAG = MyApplication.class
            .getSimpleName();

    private RequestQueue mRequestQueue;

    private static MyApplication mInstance;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }

    public static synchronized MyApplication getInstance() {
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }

        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req, String tag) {
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }

    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }

    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

5. Open AndroidManifest.xml and add MyApplication.java class to <application> tag. Also you need to add INTERNET permission as we need to make http calls.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.androidhive.swiperefresh">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:name=".app.MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".activity.MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

6. Now let’s create a custom adapter class for our list view. Under res ⇒ layout folder, create an xml layout named list_row.xml. This xml renders single list row in the ListView.

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

    <TextView
        android:id="@+id/serial"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="25dp"
        android:layout_margin="5dp"
        android:layout_alignParentLeft="true"
        android:textSize="20dp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/title"
        android:layout_toRightOf="@id/serial"
        android:layout_centerVertical="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:paddingLeft="20dp"
        android:textSize="18dp" />

</RelativeLayout>

7. Under helper package, create a java class named Movie.java and add below code. This is a model class required to create movie objects to provide data to the List View

package info.androidhive.swiperefresh.helper;

/**
 * Created by Ravi on 13/05/15.
 */
public class Movie {
    public int id;
    public String title;

    public Movie() {
    }

    public Movie(int id, String title) {
        this.title = title;
        this.id = id;
    }
}

8. Under helper package, create another class named SwipeListAdapter.java. This class is a custom adapter class which inflates the list_row.xml by applying proper data.

package info.androidhive.swiperefresh.helper;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.List;

import info.androidhive.swiperefresh.R;

/**
 * Created by Ravi on 13/05/15.
 */
public class SwipeListAdapter extends BaseAdapter {
    private Activity activity;
    private LayoutInflater inflater;
    private List<Movie> movieList;
    private String[] bgColors;

    public SwipeListAdapter(Activity activity, List<Movie> movieList) {
        this.activity = activity;
        this.movieList = movieList;
        bgColors = activity.getApplicationContext().getResources().getStringArray(R.array.movie_serial_bg);
    }

    @Override
    public int getCount() {
        return movieList.size();
    }

    @Override
    public Object getItem(int location) {
        return movieList.get(location);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (inflater == null)
            inflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null)
            convertView = inflater.inflate(R.layout.list_row, null);

        TextView serial = (TextView) convertView.findViewById(R.id.serial);
        TextView title = (TextView) convertView.findViewById(R.id.title);

        serial.setText(String.valueOf(movieList.get(position).id));
        title.setText(movieList.get(position).title);

        String color = bgColors[position % bgColors.length];
        serial.setBackgroundColor(Color.parseColor(color));

        return convertView;
    }

}

10. Now we have all the required files in place, let’s start implementing the actual swipe refresh view. Open the layout file of your main activity (activity_main.xml) and modify the layout as shown below. I have added a ListView to show list of movies and wrapped it around SwipeRefreshLayout to get the swipe to refresh.

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ListView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/listView">

    </ListView>

</android.support.v4.widget.SwipeRefreshLayout>

11. Finally open MainActivity.java and do the below changes to achieve the swipe refresh list view.

> Implement the activity from SwipeRefreshLayout.OnRefreshListener and override the onRefresh() method.

> Call fetchMovies() which is a volley’s json array call to fetch the json and update the list view.

> onRefresh() is triggered whenever user swipes down the view. So call fetchMovies() inside this method to get the next set of movies response.

package info.androidhive.swiperefresh.activity;

import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.widget.ListView;
import android.widget.Toast;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

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

import info.androidhive.swiperefresh.R;
import info.androidhive.swiperefresh.app.MyApplication;
import info.androidhive.swiperefresh.helper.Movie;
import info.androidhive.swiperefresh.helper.SwipeListAdapter;


public class MainActivity extends ActionBarActivity implements SwipeRefreshLayout.OnRefreshListener {

    private String TAG = MainActivity.class.getSimpleName();

    private String URL_TOP_250 = "https://api.androidhive.info/json/imdb_top_250.php?offset=";

    private SwipeRefreshLayout swipeRefreshLayout;
    private ListView listView;
    private SwipeListAdapter adapter;
    private List<Movie> movieList;

    // initially offset will be 0, later will be updated while parsing the json
    private int offSet = 0;

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

        listView = (ListView) findViewById(R.id.listView);
        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);

        movieList = new ArrayList<>();
        adapter = new SwipeListAdapter(this, movieList);
        listView.setAdapter(adapter);

        swipeRefreshLayout.setOnRefreshListener(this);

        /**
         * Showing Swipe Refresh animation on activity create
         * As animation won't start on onCreate, post runnable is used
         */
        swipeRefreshLayout.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        swipeRefreshLayout.setRefreshing(true);

                                        fetchMovies();
                                    }
                                }
        );

    }

    /**
     * This method is called when swipe refresh is pulled down
     */
    @Override
    public void onRefresh() {
        fetchMovies();
    }

    /**
     * Fetching movies json by making http call
     */
    private void fetchMovies() {

        // showing refresh animation before making http call
        swipeRefreshLayout.setRefreshing(true);

        // appending offset to url
        String url = URL_TOP_250 + offSet;

        // Volley's json array request object
        JsonArrayRequest req = new JsonArrayRequest(url,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        Log.d(TAG, response.toString());

                        if (response.length() > 0) {

                            // looping through json and adding to movies list
                            for (int i = 0; i < response.length(); i++) {
                                try {
                                    JSONObject movieObj = response.getJSONObject(i);

                                    int rank = movieObj.getInt("rank");
                                    String title = movieObj.getString("title");

                                    Movie m = new Movie(rank, title);

                                    movieList.add(0, m);

                                    // updating offset value to highest value
                                    if (rank >= offSet)
                                        offSet = rank;

                                } catch (JSONException e) {
                                    Log.e(TAG, "JSON Parsing error: " + e.getMessage());
                                }
                            }

                            adapter.notifyDataSetChanged();
                        }

                        // stopping swipe refresh
                        swipeRefreshLayout.setRefreshing(false);

                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Server Error: " + error.getMessage());

                Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();

                // stopping swipe refresh
                swipeRefreshLayout.setRefreshing(false);
            }
        });

        // Adding request to request queue
        MyApplication.getInstance().addToRequestQueue(req);
    }

}

Run the project and test it. You should able see the swipe refresh animation on app launch and list view updated each time you swipe down it.

android swipe down to refresh listview

4. PHP Class to Generate JSON

As lot of people are requesting me to provide the PHP code to generate the json, I am giving the code to generate the json used in this article. You can run this code using WAMP or XAMP softwares. Checkout Video 1 and Video 2 for installation and running PHP project in WAMP.

<?php

// sleep for 2 sec show that the androd swipe refresh will be visible for sometime
sleep(2);

// all top 250 movies
$movies = array("The Shawshank Redemption", "The Godfather", "The Godfather: Part II", "The Dark Knight", "Pulp Fiction", "Schindler's List", "12 Angry Men", "The Good, the Bad and the Ugly", "The Lord of the Rings: The Return of the King", "Fight Club", "The Lord of the Rings: The Fellowship of the Ring", "Star Wars: Episode V - The Empire Strikes Back", "Forrest Gump", "Inception", "One Flew Over the Cuckoo's Nest", "The Lord of the Rings: The Two Towers", "Goodfellas", "The Matrix", "Star Wars", "Seven Samurai", "City of God", "Se7en", "The Usual Suspects", "The Silence of the Lambs", "It's a Wonderful Life", "Interstellar", "Léon: The Professional", "Life Is Beautiful", "Once Upon a Time in the West", "Casablanca", "American History X", "Saving Private Ryan", "Spirited Away", "Raiders of the Lost Ark", "City Lights", "Psycho", "Rear Window", "The Intouchables", "Whiplash", "Modern Times", "The Green Mile", "Terminator 2: Judgment Day", "Memento", "The Pianist", "The Departed", "Apocalypse Now", "Gladiator", "Sunset Blvd.", "Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb", "Back to the Future", "Alien", "The Prestige", "The Lion King", "The Great Dictator", "The Lives of Others", "Cinema Paradiso", "Django Unchained", "The Shining", "Paths of Glory", "The Dark Knight Rises", "American Beauty", "WALL·E", "North by Northwest", "Aliens", "Citizen Kane", "Grave of the Fireflies", "Vertigo", "M", "Oldboy", "Das Boot", "Amélie", "Princess Mononoke", "Star Wars: Episode VI - Return of the Jedi", "Once Upon a Time in America", "Toy Story 3", "Reservoir Dogs", "A Clockwork Orange", "Braveheart", "Taxi Driver", "Double Indemnity", "Witness for the Prosecution", "Requiem for a Dream", "To Kill a Mockingbird", "Lawrence of Arabia", "Eternal Sunshine of the Spotless Mind", "Full Metal Jacket", "Bicycle Thieves", "The Sting", "Singin' in the Rain", "Amadeus", "Monty Python and the Holy Grail", "Snatch.", "2001: A Space Odyssey", "For a Few Dollars More", "Rashomon", "L.A. Confidential", "The Kid", "All About Eve", "The Apartment", "Inglourious Basterds", "Toy Story", "The Treasure of the Sierra Madre", "A Separation", "Indiana Jones and the Last Crusade", "Yojimbo", "The Third Man", "Some Like It Hot", "Metropolis", "Batman Begins", "Unforgiven", "Scarface", "Like Stars on Earth", "Raging Bull", "Up", "3 Idiots", "Downfall", "Chinatown", "The Great Escape", "Die Hard", "The Hunt", "On the Waterfront", "Heat", "Mr. Smith Goes to Washington", "Pan's Labyrinth", "Good Will Hunting", "The Bridge on the River Kwai", "My Neighbor Totoro", "Ikiru", "The Seventh Seal", "The Gold Rush", "Ran", "Wild Strawberries", "The General", "Blade Runner", "The Elephant Man", "Lock, Stock and Two Smoking Barrels", "The Secret in Their Eyes", "The Wolf of Wall Street", "Casino", "Gran Torino", "Howl's Moving Castle", "Warrior", "The Big Lebowski", "V for Vendetta", "Rebecca", "The Bandit", "Gone Girl", "The Deer Hunter", "Judgment at Nuremberg", "Cool Hand Luke", "How to Train Your Dragon", "It Happened One Night", "Fargo", "A Beautiful Mind", "Gone with the Wind", "Trainspotting", "Into the Wild", "Rush", "Dial M for Murder", "The Maltese Falcon", "The Sixth Sense", "Mary and Max", "Finding Nemo", "The Thing", "The Wages of Fear", "Hotel Rwanda", "No Country for Old Men", "Incendies", "Rang De Basanti", "Kill Bill: Vol. 1", "Platoon", "Life of Brian", "Butch Cassidy and the Sundance Kid", "Network", "A Wednesday", "Munna Bhai M.B.B.S.", "Touch of Evil", "There Will Be Blood", "12 Years a Slave", "Annie Hall", "The 400 Blows", "Stand by Me", "The Princess Bride", "Persona", "The Grand Budapest Hotel", "Amores Perros", "Ben-Hur", "Diabolique", "In the Name of the Father", "The Grapes of Wrath", "Million Dollar Baby", "Sin City", "Hachi: A Dog's Tale", "Nausicaä of the Valley of the Wind", "The Wizard of Oz", "The Best Years of Our Lives", "Gandhi", "The Avengers", "The Bourne Ultimatum", "Donnie Darko", "Shutter Island", "Stalker", "8½", "Guardians of the Galaxy", "Strangers on a Train", "Infernal Affairs", "Twelve Monkeys", "Fanny and Alexander", "Before Sunrise", "Boyhood", "Jaws", "The Imitation Game", "The Battle of Algiers", "The Terminator", "High Noon", "Groundhog Day", "Harry Potter and the Deathly Hallows: Part 2", "Memories of Murder", "The King's Speech", "Ip Man", "Monsters, Inc.", "Notorious", "Rocky", "Dog Day Afternoon", "Barry Lyndon", "La Haine", "The Truman Show", "Who's Afraid of Virginia Woolf?", "A Fistful of Dollars", "Dil Chahta Hai", "The Night of the Hunter", "Pirates of the Caribbean: The Curse of the Black Pearl", "Lagaan: Once Upon a Time in India", "Castle in the Sky", "Jurassic Park", "X-Men: Days of Future Past", "La Strada", "The Help", "Roman Holiday", "Wild Tales", "The Big Sleep", "Spring, Summer, Fall, Winter... and Spring", "Le Samouraï", "Prisoners", "Underground", "The Graduate", "Paris, Texas", "Solaris", "Three Colors: Red", "Papillon");

// reading offset from get parameter
$offset = isset($_GET['offset']) && $_GET['offset'] != '' ? $_GET['offset'] : 0;

// page limit
$limit = 20;


$movies_array = array();

// loop through page movies
for ($j = $offset; $j < $offset + $limit && $j < sizeof($movies); $j++) {
    $tmp = array();
    $tmp['rank'] = $j + 1;
    $tmp['title'] = $movies[$j];

    array_push($movies_array, $tmp);
}

// printing json response
echo json_encode($movies_array);
?>
Ravi is hardcore Android programmer and Android programming has been his passion since he compiled his first hello-world program. Solving real problems of Android developers through tutorials has always been interesting part for him.
  • nice

  • Aw Oo

    can you give me example of acces url = domain.com/example.php without param offset or anything?. an example my url above, return result from db like this = [ { “id”: “1”, “nama”: “Nasi Goreng Beringharjo” }, { “id”: “2”, “nama”: “Gudeg Pawon”} ] .

  • Arjun

    Nice one .
    Hi Ravi, can you please tell me what are handlers , loaders and adapters in android and what are they used for . I read the documentations from developer site but couldn’t understand them. Please help. Thank you

  • Sithu

    Nice Tutorial,
    Hi Ravi, this is the swipe down to refresh function. I want to know the swipe up to refresh list view. Please help . Thanks.

  • Dharmik

    Ravi, Doing a Great Job 🙂

  • slim

    nice work

  • xxx

    hmmmm

  • Sad And Smile

    i am getting Index out of bound exception when I tap pull down refresh for multiple times. Can u tell me how to fix it?

  • Игорь

    Прекрасно! Спасибо за Ваши уроки, как всегда все отлично работает.

  • Andra Galih

    New Fans here.. Always Awesome Tutorial Article.. Keep Up The Good Work…

  • sapamlucy

    i follow ur blogs n i learnt android programming using ur blogs only n it has been fun.. but somehow this inclusion of php has been hard to follow because i dont knw php… i hope, though it might be essential to use php , u provide articals which uses uses solely java…(in scenarios like this so that we know how it done.. if thats not asking too much). thanks for sharing ur knowledge

    • Hi Sapamlucy,

      Actually I can build the same in java too instead of PHP, but hosting java servers are costlier than PHP. That’s why I always wanted to give server side part in PHP. May be from next time onwards I should prefer giving everything in java.

      Cheers!

      • sapamlucy

        I realize u have a valid point here but Thank u for considering my suggestion !!

  • Trey Rosius

    Simple and straight forward…Thanks Ravi. I’de already implemented this in an app, but i still dig your implementation…Great Work

  • inside onRefresh() the fetchMovies() method should be in Handler to avoid errors when you click on any item in listView or RecycleView and Stop it ..

    thank u nice Tutorial @_@ ;

    • Thanks Ahmad for your tip 🙂

    • erhan harmankaya

      hi how can we change the code ?

  • Jaymo Left Brained

    Just an extra tip, you can customize the SwipeRefreshLayout’s animated loader

    swipeRefreshLayout.setColorSchemeResources(R.color.blue,R.color.red);

  • Roshan W

    Please Add Tutorial For SwipeRefreshLayout Like Gmail

    Ref: http://antonioleiva.com/swiperefreshlayout/

    &

    http://www.touchmeco.tk/android-swipe-down-to-refresh-now-easy-with-swiperefreshlayout

    Tried Above But Not Working !

  • Karthik

    Very clear and simply explained. Thanks..

  • Renitto Jose

    Thank you for the Tutorial . Can you Please Provide a Tutorial about ShowCaseView library With a Sample .

  • Renitto Jose

    How to Provide a Zooming Effect for the SwipeRefreshLayout like in Drippler App .
    https://play.google.com/store/apps/details?id=com.drippler.android.updates&hl=en

  • Mohammad

    Ravi, Doing a Great Job 🙂

  • Raja Veeramani

    Hi Ravi, You are doing a great job. Very informative.
    Would you be available to work on a side project? Thanks!

  • Akshay

    it will get triggerred whenever i scroll down from my list view. Is is possible to activate it only from the top of the list. thanks

  • Ravi, i’ve a request. Could please make some tutorial about creating `Custom Views` in Android.

    • ravi

      ok keep updatng.

  • Ghed Oneraj

    Please Add Live Wallpaper tutorial,Using .gif file Or on Particular Time Wallpaper Autometically change Wallpaper

    • ravi

      ok

  • Muhammad Faridh Djamalilleil

    Hey Ravi, I have been developing android app using view pager and material design navigation drawer and I want to use SwipeRefreshLayout in some of my fragment classes that retrieve data from database server. Can I make it on Fragment as main class? if can how do I have to change the adapter class and use data from database? Thanks in advance. Cheers! 🙂

  • Hey Ravi,
    It’s been nice and awesome tutorials. Its so helping. Great work, Thanks.

  • test’s

    Hi nice’s Look up .
    hii
    ” Every thing’s it’s a new functionality “. Looking nice12#.

  • karampal

    can any one tell me how use this swipe down refresh with parse.com

  • Minor detail, on point 6, while creating the list_row.xml, you have used android:orientation=”horizontal” attribute on a RelativeLayout. The attribute is only available to LinearLayout and its subclasses

  • preyas

    post

  • mostafa

    thank you bacause of your tutorials
    please show us how can we extend layouts like search view on google play store or whats app atachment layout

  • Archana C R

    It’s been nice and awesome tutorials. Its so helping. Great work, Thanks

  • Manny264

    When it initially loads and you pull up again it just keep on refreshing but no action. It wont even cancel and LogCat wont pick it up. How can that be fixed?

  • sreeshty raychoudhury

    nice ….can you do demo for basic game tutorial for android

  • Kira Browdy

    Hi Ravi,
    I would like to advertise on your website but can’t find your email.
    Please contact me for details!
    THanks

  • Sarthak Majithia

    I am implementing this for a list inside a fragment view. When I scroll down and then scroll up again, it starts to refresh, how to refresh only when the user has reached back to top item in the list?

  • simple gats

    ravi.. why you don’t use recyclerview to replace listview…

  • vgnc

    If your list is duplicating when you refresh clear the movieList before you refresh:

    @Override
    public void onRefresh() {
    movieList = new ArrayList();
    fetchMovies();
    }

    • MOOC SHARE

      Thank you so much. It works.

    • MOOC SHARE

      Hello Man, If I use the above, I didn’t get any update. To update I have to reopen the class. Do you why it was that?

    • Julian

      it does’nt work for me?

  • Anna Katzen

    Is it free for commercial use?

  • Pronab

    java.lang.NullPointerException
    at swipe.com.down.activity.MainActivity.fetchMovies(MainActivity.java:149)
    fetchMovies(); error Please Help.

  • Madhur Vaish

    The Code Is Good,but the application crashes abnormally!!

    Can you provide me with some solution to this problem.

    These are the list of errors generated in Logcat
    07-22 17:47:52.662 22040-22040/? E/AndroidRuntime﹕ FATAL EXCEPTION: main

    Process: example.com.refresh, PID: 22040

    java.lang.NullPointerException: Attempt to invoke virtual method ‘void app.MyApplication.addToRequestQueue(com.android.volley.Request)’ on a null object reference

    at example.com.refresh.MainActivity.fetchMovies(MainActivity.java:127)

    at example.com.refresh.MainActivity.access$100(MainActivity.java:26)

    at example.com.refresh.MainActivity$1.run(MainActivity.java:59)

    at android.os.Handler.handleCallback(Handler.java:739)

    at android.os.Handler.dispatchMessage(Handler.java:95)

    at android.os.Looper.loop(Looper.java:145)

    at android.app.ActivityThread.main(ActivityThread.java:5832)

    at java.lang.reflect.Method.invoke(Native Method)

    at java.lang.reflect.Method.invoke(Method.java:372)

    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)

    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)

    • Priyanka Gupta

      U have not added a line in android menifest.
      under application tag like…
      android:name=”MyApplication”

  • Madhur Vaish, can u try debug.

  • Hi, I implemented the same example as in this post, but instead of Listiview, I used a recyclerView wrapped within a SwipeRefreshLayout element, !! Thanks !!

    • ARASHI Funsho

      I did the same too, but implemented within a fragments in TabLayout 😉

  • shubham

    Can you show us how we can implement this using Parse?

    • I am not sure about it. But it should be same as this. You need to parse the json provided by parse.com and do the same.

      • shubham

        Thanks for replying, I’ll try that, what if I just fetch the whole list again when the user swipes down?

  • dsa

    sdfdsfdsfds

  • hamed Ghadirian

    tanX

  • Fəqan Çələbizadə

    Hi Ravi. How to do it as gmail style?

  • Thanks. how to cache by volley when we dont have internet connection?

  • David Rivas

    God Bless you men!!.

  • immi

    hai! i m new to android and having the follwoing problem.
    what will be the sample function to retrieve data from database using volley library .for example if i have a table having three columns id,first_name,last_name .how will be the android function for retrieve operation. please help

    • MOOC SHARE

      StringRequest strReq = new StringRequest(Request.Method.POST,
      url, new Response.Listener() {

      @Override
      public void onResponse(String response) {
      Log.d(TAG, response.toString());

      try {
      JSONObject responseObj = new JSONObject(response);
      boolean error = responseObj.getBoolean(“error”);
      String message = responseObj.getString(“message”);
      System.out.println(“Message: ” + message);

      if(!error){

      JSONArray profileObj = responseObj.getJSONArray(“info_submit_call”);
      int len = profileObj.length();
      Global.status = new String[len];

      if (profileObj != null){
      for (int i = 0; i < profileObj.length(); i++) {
      JSONObject movieObj = profileObj.getJSONObject(i);
      String rank = movieObj.getString("phoneTransfer");
      String title = movieObj.getString("phoneReceiver");
      String status_string = movieObj.getString("status");

  • Timothy Trisnadhama

    Hey Ravi,

    Great tutorial. I do have a question though, since your list display it descending order, how do you do it for ascending order?

    Thanks a lot!

    • Timothy Trisnadhama

      nvm… i got it… thanks….

      • MOOC SHARE

        How do you do that? I got this problems too.

        • MOOC SHARE

          I go it now. Just change movieList.add(0, m); to movieList.add(m);

  • ahmad

    plz i need help i got error
    10-14 23:52:07.493 2429-2429/com.example.ahmad.swipdown E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NullPointerException
    at com.example.ahmad.swipdown.activity.MainActivity.fetchMovies(MainActivity.java:151)
    at com.example.ahmad.swipdown.activity.MainActivity.access$100(MainActivity.java:27)
    at com.example.ahmad.swipdown.activity.MainActivity$1.run(MainActivity.java:70)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4745)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)

  • Santosh Thorani

    Thnak you very much.. very nice tutorial..
    your final output image has a different progress bar when the list refresh. how can we achieve that?

  • erhan harmankaya

    Hi Ravi, if you tab screen quickly 1-2 times while SwipeRefresh animation shown, Index OutofBound exception has been throw. Could you make a patch for it ? t

    Thanks

  • Mayun Kepakisan

    i have problem if put down swipe in list array show doble, triple etc., i got example JSON Url: http://api.androidhive.info/json/movies.json ? What must i doing?

    • tayfun

      same problem ..

  • Ravi, do yo have tutorial scrolldown listview to load more news using volley?

  • reymond

    how to swipe up to refresh ?

  • MOOC SHARE

    I don’t want to add elements if database is no update. Could you please explain?

  • MOOC SHARE

    notifyDataSetChanged not updating ListView. Can anyone help?

    • Khiem Nguyen Dang

      U add more movieList.clear(); into function onRefresh. I don’t know why but i think Volley have problem cache.:D
      The first, I also create new Object ArrayList but It don’t still change data.
      U can see below::)

      @Override

      public void onRefresh() {
      ovieList.clear();
      fetchMovies();

      }

  • MOOC SHARE

    Now I can update listview by creating a fuction.

    public void refresh_class(){
    listView = (ListView) findViewById(R.id.listview_submit_call);
    swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);

    movieList = new ArrayList();
    adapter = new SwipeListAdapter(this, movieList);
    listView.setAdapter(adapter);
    listView.setOnItemClickListener(this);

    swipeRefreshLayout.setOnRefreshListener(this);

    /**
    * Showing Swipe Refresh animation on activity create
    * As animation won’t start on onCreate, post runnable is used
    */
    swipeRefreshLayout.post(new Runnable() {
    @Override
    public void run() {
    swipeRefreshLayout.setRefreshing(true);

    fetchMovies();
    }
    }
    );
    }

    And call it again onRefresh(): function.

  • saeed

    good

  • gunjan

    when we select any item in the list ,then how it will give information about that movie?

    • Faissal Nabil

      Movie o = (Movie) parent.getItemAtPosition(position);
      String Title = o.getTitle()….etc

  • Miyu Kazu

    Hi, I’m a beginner and would like to ask for your help.
    What if my data wouldn’t come from JSON, instead it will be coming from a SQLite database, how should I pull the data from it?

    • You can read the data from SQlite add it to listview adapter when list view is pulled down.

      • Miyu Kazu

        thank you so much for the reply.. but I am still confuse as I am still a beginner.
        how about putting the limit per refresh? I saw that you put the limit on JSON..
        Thank you so much for your time

        • First of all Swipe to Refresh list won’t be used with SQLite as data will be always available with the device. It is used to fetch new data from a server.

          If your app insist to use it, read the below article get an understanding of how SQLite will work and how to query the data.

          http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/

          Next write a function which takes the column id and return the next 10 or 20 rows greater than that id. Check the below function (not tested)

          public List getAllContacts(String columnId) {
          List contactList = new ArrayList();
          // Select All Query
          String selectQuery = “SELECT * FROM ” + TABLE_CONTACTS + ” ” + KEY_ID + ” > ” + columnId + ” LIMIT 10″;

          SQLiteDatabase db = this.getWritableDatabase();
          Cursor cursor = db.rawQuery(selectQuery, null);

          // looping through all rows and adding to list
          if (cursor.moveToFirst()) {
          do {
          Contact contact = new Contact();
          contact.setID(Integer.parseInt(cursor.getString(0)));
          contact.setName(cursor.getString(1));
          contact.setPhoneNumber(cursor.getString(2));
          // Adding contact to list
          contactList.add(contact);
          } while (cursor.moveToNext());
          }

          // return contact list
          return contactList;

          • Miyu Kazu

            Hi, thank you so much for your reply. I tried and apply the code you send but still can’t make it to run 🙁

            I also read the other tutorial about SQLite database and was able to understand it.

            My problem now is that how can I get the latest id of a row on the listview after the refresh so the next one that will appear will be the row below it when refreshed again.

            If it’s ok, can you give me a sample?

            Thank you so much!

          • Give me your code where at least you could able to fetch first 10 rows from SQLite.

          • Miyu Kazu

            Hi, Thanks again for the reply. Here’s my code for the db operation. I want to fetch 2 rows at a time:

            public Cursor displaySwipeInfo(SQLiteDatabase db, int itmId) {

            String[] projections = {ItemContract.ItemEntry.ID, ItemContract.ItemEntry.NAME,

            ItemContract.ItemEntry.QTY, ItemContract.ItemEntry.PRICE};

            Cursor display_cursor_swipe = db.query(ItemContract.ItemEntry.TABLE_NAME, projections, ItemContract.ItemEntry.ID + ” > ” + itmId , null, null, null, “2”);

            return display_cursor_swipe;

            }

            ——————————————————————-

            Here’s my code for the onRefresh():

            public void onRefresh() {

            fetchItems();

            }

            private void fetchItems() {

            swipeRefreshLayout.setRefreshing(true);

            list_view = (ListView) findViewById(R.id.lvDisplay);

            DatabaseOperations db_op_sw = new DatabaseOperations(this);

            SQLiteDatabase db = db_op_sw.getReadableDatabase();

            int offSet = 0;

            Cursor display_cursor_swipe = db_op_sw.displaySwipeInfo(db, offSet);

            itm_adapter = new ItemAdapter(this, R.layout.view_item_row);

            String name;

            int id, qty, price;

            if (display_cursor_swipe.moveToFirst()) {

            do {

            id = display_cursor_swipe.getInt(display_cursor_swipe.getColumnIndex(ItemContract.ItemEntry.ID));

            name = display_cursor_swipe.getString(display_cursor_swipe.getColumnIndex(ItemContract.ItemEntry.NAME));

            qty = display_cursor_swipe.getInt(display_cursor_swipe.getColumnIndex(ItemContract.ItemEntry.QTY));

            price = display_cursor_swipe.getInt(display_cursor_swipe.getColumnIndex(ItemContract.ItemEntry.PRICE));

            Item item = new Item(id, name, qty, price);

            itm_adapter.add(item);

            offSet++;

            } while (display_cursor_swipe.moveToNext());

            itm_adapter.notifyDataSetChanged();

            }

            list_view.setAdapter(itm_adapter);

            swipeRefreshLayout.setRefreshing(false);

            }

            ——————————–

            I really don’t know if I got the onRefresh() part correct.. I am really new to this and really stuck

            Thank you so much for your time

  • Anubhav

    Data is being add at bottom.Can you please help me to how to add data at tom
    .

    • Anubhav

      It’s done thanks ravi nice tutorial.5 star 🙂

  • Vjai

    Very Helpful !!

  • Micael Brito

    Nice and easy!

  • Brain

    hey ravi thanks for the tutorial, but can you help me? I want to convert your php class here into slim tutorial that you have. thanks

  • Faruqi Muhammad

    hi all, could you help me, i confused how to read 5 array from last ex: 249 248 247 246 245

    for ($j = sizeof($movies); $j > sizeof($movies) – $limit ; $j–) {

    // offset 0 , 0 + 5 dan $j

    // $tmp = array();

    // $tmp[‘rank’] = $j – 1; // + / –

    // $tmp[‘title’] = $movies[$j];

    // array_push($movies_array, $tmp);

    echo ($j-1).” “;

    }

    // printing json response

    echo json_encode($movies_array);

    … anybody can help please?

  • Sridharan Natarajan

    Thank you very much… This is very useful guide. I want to load the url data while scroll pull up the listview… can u help me…?

    • ARASHI Funsho

      were you able to implement this? if yes, please show me how…. Thanks 😉

  • Dipen

    Nice Article.
    Can you please share an article for Swipe to delete for listview and expandable listview?

  • Slava

    Thanks!

  • ARASHI Funsho

    Ok Ravi, I found it.

  • Gaurav Arya Singh

    i am having error in style.xml file,,, this is silly nut i really messed up… please help

    • What is the error? Update your Android Studio, build tools and create a new project.

  • rits

    what is jSON anyone tell me????
    plss

  • Wetcha Chaima

    lov lov lov u man you’re my hero again ^_^

  • Julian

    I do excactly what you did in this tutorial, but the list was duplicated although it have no change. When I refreshed the list, the existing items were added to the list too.

    • Shubham Gupta

      Hey Jullan, this is because you have not cleared your data in the adapter. Therefore it is adding the same data again. When calling swipe refresh, first remove any data you have. I suppose you are using array list to add data. If you are, then call the ArrayListObjectName.clear() method first.

      • Suyash Mishra

        Thank you Shubham Gupta

  • Ashutosh Tripathi

    Hi, does this also work with recycler view

  • Mudit Gupta

    I have done the same exact thing as given in the tutorial but the app is getting crashed on
    MyApplication.getInstance().addToRequestQueue(req);

    the logcat is showing NullPOinterException

  • Nik

    Hi, In my case, refresh Animation freezes, I used ” layout.post ” method as you suggested but inside post method My list comes from sdk and that is on main thread so it stops animation. I also tried to put sdk method inside Asynch task but it won’t work.
    Second is, If I use “postDelayed” method instead of “post” method than how can i set timer so that method inside that method runs and at that time i will use setRefreshing = false

  • Jaya Gautam

    Hi Ravi Tamada,

    Your all tutorials are very helpful and easy to understand.
    Presently, i am showing database data in recyclerview on swipe listener but data in recyclerview is lost onCreate.

    Please give some advice.

    Thanks in advance.

  • Deepak Rao

    Nice tutorial. What max data list view can handle? I want to show temperature variance every hour. so data in list view becomes huge. What is best practise in such satuations ?

  • Jae-Min Kim

    This is a great tutorial!
    If you want to see the rank from the top you need to change the code below.

    movieList.add(rank – 1, m);

    Well done!

  • Johnny

    Hi Is it posible to change color of arrow???

    • Johnny

      Oh i found it now… Nice component (y)

  • Harish

    hi ravi,
    How to add subitems under listview..? I have a requirement where list view contains subitems. when i click it will expand that too only for third element. and for each view it will open a separate fragment. Its a urgent requirement. Please can anyone help

  • Gaurav meghanathi

    i want to refresh list when i retrieve my local database list during the new asynctask class call i set list data into recyclerview but unfortunately i made code look like……………………………………
    public class DealFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener{

    public DealFragment() {
    // Required empty public constructor
    }

    private RecyclerView recyclerView, recyclerViewDeals;
    private TextView txtStatus, txtStatusDeals;
    private ProgressBar progressBar, progressBarDeals;
    private TextView lbTopSelling;
    private ArrayList categoryList;
    private ArrayList dealList,dList;
    private int page = 1;
    private WrappingLinearLayoutManager mLayoutManager;
    private DATABASE_HELPER helper;
    private IndexCategoryModel indexCategoryModel;
    private CityModel cityModel;
    private IndexCategoryAdapter indexCategoryAdapter;
    private SwipeRefreshLayout swipeRefreshLayout;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_deal, container, false);

    init(view);
    LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mMessageReceiver,
    new IntentFilter(“refreshIndexData”));

    refreshData();
    setClickListner();

    return view;
    }

    private void setClickListner() {

    recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
    @Override
    public void onItemClick(View view, int position) {
    Intent intent = new Intent(getActivity(),CategoryWiseDealActivity.class);
    intent.putExtra(“categoryId”,categoryList.get(position).getCategory_id());
    intent.putExtra(“categoryTitle”,categoryList.get(position).getCategory_title());
    startActivity(intent);
    }

    @Override
    public void onLongItemClick(View view, int position) {

    }
    }));

    recyclerViewDeals.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), recyclerViewDeals, new RecyclerItemClickListener.OnItemClickListener() {
    @Override
    public void onItemClick(View view, int position) {
    Intent intent = new Intent(getActivity(),DealDetailActivity.class);
    intent.putExtra(“dealUniqueId”,dealList.get(position).getDeal_unique_id());
    startActivity(intent);
    }

    @Override
    public void onLongItemClick(View view, int position) {

    }
    }));
    recyclerViewDeals.addOnScrollListener(new EndlessRecyclerViewScrollListener(mLayoutManager) {
    @Override
    public void onLoadMore(int page, int totalItemsCount) {
    new DealsAsync().execute(page + “”);
    }
    });
    }

    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
    // Get extra data included in the Intent
    String message = intent.getStringExtra(“refresh”);
    Log.d(“receiver”, “Got message: ” + message);
    refreshData();
    }
    };

    @Override
    public void onDestroy() {
    // Unregister since the activity is about to be closed.
    LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mMessageReceiver);
    super.onDestroy();
    }

    private void init(View view) {

    recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
    swipeRefreshLayout = (SwipeRefreshLayout)view.findViewById(R.id.swipe_refresh_layout);
    // RecyclerView.LayoutManager mLayoutManager = new WrappingLinearLayoutManager(getApplicationContext());
    recyclerView.setNestedScrollingEnabled(false);
    recyclerView.setHasFixedSize(false);
    recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
    recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, 20, false));

    progressBar = (ProgressBar) view.findViewById(R.id.progressBar);

    txtStatus = (TextView) view.findViewById(R.id.txtStatus);
    FontUtils.setRegular(txtStatus, getActivity());

    recyclerViewDeals = (RecyclerView) view.findViewById(R.id.recyclerViewDeals);
    mLayoutManager = new WrappingLinearLayoutManager(getActivity());
    recyclerViewDeals.setNestedScrollingEnabled(false);
    recyclerViewDeals.setHasFixedSize(false);
    recyclerViewDeals.setLayoutManager(mLayoutManager);
    // recyclerViewDeals.addItemDecoration(new GridSpacingItemDecoration(2, 20, false));

    progressBarDeals = (ProgressBar) view.findViewById(R.id.progressBarDeals);

    txtStatusDeals = (TextView) view.findViewById(R.id.txtStatusDeals);
    FontUtils.setRegular(txtStatusDeals, getActivity());

    lbTopSelling = (TextView) view.findViewById(R.id.lbTopSelling);
    FontUtils.setRegular(lbTopSelling, getActivity());

    categoryList = new ArrayList();
    helper = new DATABASE_HELPER(getActivity()); //here getting data from local db.
    /*
    // CommonUtils.toastShort(getActivity(),categoryList.size()+””); //here getting data from local db.
    categoryList = helper.getAll_Index_Category();
    indexCategoryAdapter= new IndexCategoryAdapter(getActivity(),categoryList);

    recyclerView.setAdapter(indexCategoryAdapter);
    indexCategoryAdapter.notifyDataSetChanged();*/

    //Swipe view to refresh list item.

    swipeRefreshLayout.setOnRefreshListener(DealFragment.this);
    swipeRefreshLayout.post(new Runnable() {
    @Override
    public void run() {

    swipeRefreshLayout.setRefreshing(true);
    new CategoryAsync().execute();
    //here getting data from local db.

    // CommonUtils.toastShort(getActivity(),categoryList.size()+””); //here getting data from local db.
    /* categoryList = helper.getAll_Index_Category();
    indexCategoryAdapter= new IndexCategoryAdapter(getActivity(),categoryList);;

    recyclerView.setAdapter(indexCategoryAdapter);
    indexCategoryAdapter.notifyDataSetChanged();
    swipeRefreshLayout.setRefreshing(false);*/

    }
    });

    dealList = new ArrayList();
    dList = new ArrayList();
    }

    @Override
    public void onRefresh() {

    swipeRefreshLayout.setRefreshing(true);
    new CategoryAsync().execute();
    /* helper = new DATABASE_HELPER(getActivity()); //here getting data from local db.

    // CommonUtils.toastShort(getActivity(),categoryList.size()+””); //here getting data from local db.
    categoryList = helper.getAll_Index_Category();
    indexCategoryAdapter= new IndexCategoryAdapter(getActivity(),categoryList);;

    recyclerView.setAdapter(indexCategoryAdapter);
    indexCategoryAdapter.notifyDataSetChanged();
    swipeRefreshLayout.setRefreshing(false);*/

    }

    public class CategoryAsync extends AsyncTask {

    ParsedResponse parsedResponse;

    @Override
    protected void onPreExecute() {
    super.onPreExecute();
    progressBar.setVisibility(View.VISIBLE);
    txtStatus.setVisibility(View.GONE);
    recyclerView.setVisibility(View.GONE);
    }

    @Override
    protected String doInBackground(String… params) {

    ServiceHandler sh = new ServiceHandler();
    try {
    parsedResponse = sh.apiIndexCategory(getActivity());
    } catch (Exception e) {
    e.printStackTrace();
    }
    return null;
    }

    @Override
    protected void onPostExecute(String s) {
    super.onPostExecute(s);
    if (parsedResponse != null) {
    String message = parsedResponse.getMessage();
    txtStatus.setText(message);
    Log.i(“WebService MESSAGE”,message);
    // CommonUtils.toastShort(getActivity(), message);
    if(!parsedResponse.isError()) {
    //noinspection unchecked
    // categoryList = (ArrayList) parsedResponse.getObject();
    categoryList = helper.getAll_Index_Category();
    if (categoryList.size() > 0) {
    indexCategoryAdapter= new IndexCategoryAdapter(getActivity(), categoryList);
    recyclerView.setAdapter(indexCategoryAdapter);
    indexCategoryAdapter.notifyDataSetChanged();

    recyclerView.setVisibility(View.VISIBLE);
    txtStatus.setVisibility(View.GONE);
    progressBar.setVisibility(View.GONE);

    swipeRefreshLayout.setRefreshing(false);
    } else {
    recyclerView.setVisibility(View.GONE);
    txtStatus.setVisibility(View.VISIBLE);
    progressBar.setVisibility(View.GONE);
    }

    } else {
    //here set condition if No internet connection

    //this if condition is belong to database list get and set when No Internet connection.

    if(message.contentEquals(“No Internet Connection”))
    {
    categoryList = helper.getAll_Index_Category();
    if (categoryList.size() > 0) {
    indexCategoryAdapter= new IndexCategoryAdapter(getActivity(), categoryList);
    recyclerView.setAdapter(indexCategoryAdapter);
    indexCategoryAdapter.notifyDataSetChanged();

    recyclerView.setVisibility(View.VISIBLE);
    txtStatus.setVisibility(View.GONE);
    progressBar.setVisibility(View.GONE);
    }
    }else
    {
    recyclerView.setVisibility(View.GONE);
    txtStatus.setVisibility(View.VISIBLE);
    progressBar.setVisibility(View.GONE);
    }

    }
    }
    }
    }

    public class DealsAsync extends AsyncTask {

    ParsedResponse parsedResponse;

    @Override
    protected void onPreExecute() {
    super.onPreExecute();
    progressBarDeals.setVisibility(View.VISIBLE);
    txtStatusDeals.setVisibility(View.GONE);
    recyclerViewDeals.setVisibility(View.GONE);
    }

    @Override
    protected String doInBackground(String… params) {

    String page = params[0];

    ServiceHandler sh = new ServiceHandler();
    try {
    parsedResponse = sh.apiIndexDeals(getActivity(),page);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return null;
    }

    @Override
    protected void onPostExecute(String s) {
    super.onPostExecute(s);
    if (parsedResponse != null) {
    String message = parsedResponse.getMessage();
    txtStatusDeals.setText(message);
    // CommonUtils.toastShort(getActivity(), message);
    if (!parsedResponse.isError()) {
    dealList = (ArrayList) parsedResponse.getObject();
    if (dealList.size() > 0) {
    // dList.addAll(dealList);
    recyclerViewDeals.setAdapter(new DealAdapter(getActivity(), dealList));
    recyclerViewDeals.setVisibility(View.VISIBLE);
    txtStatusDeals.setVisibility(View.GONE);
    progressBarDeals.setVisibility(View.GONE);
    } else {
    recyclerViewDeals.setVisibility(View.GONE);
    txtStatusDeals.setVisibility(View.VISIBLE);
    progressBarDeals.setVisibility(View.GONE);
    }

    } else {
    recyclerViewDeals.setVisibility(View.GONE);
    txtStatusDeals.setVisibility(View.VISIBLE);
    progressBarDeals.setVisibility(View.GONE);
    }
    }
    }
    }

    public void refreshData() {
    new CategoryAsync().execute();
    new DealsAsync().execute(page+””);
    }

    }

    My Xml File

    <!–

    Adpter class
    package com.bashayarzon.adapter;

    import android.app.Activity;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.TextView;

    import com.bashayarzon.R;
    import com.bashayarzon.model.IndexCategoryModel;
    import com.bashayarzon.utils.FontUtils;
    import com.bumptech.glide.Glide;
    import com.bumptech.glide.load.engine.DiskCacheStrategy;

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

    /**
    * Created by DSK on 8/17/2016.
    */
    public class IndexCategoryAdapter extends RecyclerView.Adapter {
    private Activity activity;
    private ArrayList list;

    public IndexCategoryAdapter(Activity activity, ArrayList list) {
    this.activity = activity;
    this.list = list;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
    .inflate(R.layout.layout_category_item, parent, false);
    return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
    final IndexCategoryModel indexCategoryModel = list.get(position);
    holder.txtCategoryName.setText(indexCategoryModel.getCategory_title());
    holder.txtDealCount.setText(indexCategoryModel.getDealCount()+” Deals”);
    String image = indexCategoryModel.getImage();
    Glide.with(activity).load(image)
    .thumbnail(0.5f)
    .crossFade()
    .diskCacheStrategy(DiskCacheStrategy.ALL)
    .into(holder.imgCategory);

    }

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

    @Override
    public long getItemId(int position) {
    return position;
    }

    public void clear() {

    list.clear();

    notifyDataSetChanged();

    }

    // Add a list of items
    public void addAll(List list) {

    list.addAll(list);
    notifyDataSetChanged();

    }

    public class ViewHolder extends RecyclerView.ViewHolder {
    private TextView txtCategoryName,txtDealCount;
    private ImageView imgCategory;
    public ViewHolder(View convertView) {
    super(convertView);
    txtCategoryName = (TextView)convertView.findViewById(R.id.txtCategoryName);
    FontUtils.setRegular(txtCategoryName,activity); //here getting null pointer

    txtDealCount = (TextView)convertView.findViewById(R.id.txtDealCount);
    FontUtils.setRegular(txtDealCount,activity);

    imgCategory= (ImageView)convertView.findViewById(R.id.imgCategory);
    }
    }

    }

  • sid

    java.lang.NullPointerException: Attempt to invoke virtual method ‘void inf.androidhiveswipe.MyApplication.addToRequestQueue(com.android.volley.Request)’ on a null object reference
    why???though am using ur URL.

    • Kondwani Z Msiska

      Am having the same problem.

      • You need to add your Application class to manifest file.

        • Kondwani Z Msiska

          Am not sure on how to add it

          • Go through the article correctly.

          • After the tag APLICATION on manifest file, just paste this code:
            android:name=”.app.MyApplication”

        • Kondwani Z Msiska

          12-29 19:47:43.730 14403-14403/malawi_music.com.entrytest E/AndroidRuntime: FATAL EXCEPTION: main

          Process: malawi_music.com.entrytest, PID: 14403

          java.lang.NullPointerException: Attempt to invoke virtual method ‘void malawi_music.com.entrytest.app.MyApplication.addToRequestQueue(com.android.volley.Request)’ on a null object reference

          at malawi_music.com.entrytest.activity.MainActivity.fetchMovies(MainActivity.java:153)
          at malawi_music.com.entrytest.activity.MainActivity.access$100(MainActivity.java:27)
          at malawi_music.com.entrytest.activity.MainActivity$1.run(MainActivity.java:67)
          at android.os.Handler.handleCallback(Handler.java:751)

          at android.os.Handler.dispatchMessage(Handler.java:95)

          at android.os.Looper.loop(Looper.java:154)

          at android.app.ActivityThread.main(ActivityThread.java:6119)

          at java.lang.reflect.Method.invoke(Native Method)

          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

        • Kondwani Z Msiska

          am still getting an error even after adding the “MyApplication” class to the android manifest. I had a problem adding it because i wouldnot add that file because it extends Application, so i changed it to extend AppCompactActivity. Please help.

  • Ahmad Rifa’i

    Hi ravi, I have difficult when I implement that php class to my code.
    Here my code:

    $result = mysqli_query($con,”SELECT * FROM data ORDER BY id DESC”);

    // check for empty result
    if (mysqli_num_rows($result) > 0) {

    $response = array();

    while ($row = mysqli_fetch_array($result)) {

    $data[‘rank’] = $row[“id”];
    $data[“address”] = $row[“address”];
    $data[“descriptions”] = $row[“descriptions”];

    array_push($response, $data);

    }

    echo json_encode($response);

    } else {

    $response[‘error’] = false;
    $response[‘message’] = ‘No data found’;

    echo json_encode($response);
    }
    mysqli_close($con);

    Can you help me?

  • Alan Kluz’em

    Thanks Ravi. You just saved me a bunch of hours………….

  • shashank tiwari

    Sir this is refreshing on sliding between tabs and on cancelling the drawer also means it’s working on every type of swipe i wanted it only on pull down to refresh how can i do it.

    • It seems, the api calls are made on fragment create method.

      • shashank tiwari

        Thanks for your reply sir but I haven’t made any api call but there is a recycler view in fragments and the problem arises when I swipe from one fragment to another or when I try to cancel drawer swiping it left

  • Cristian Gruita

    Hi, Ravi, thanks a lot. It seems, though, that the the webservice call is timing out. I cannot open the URL in browser, either. Can you double check? Thanks a lot

  • Vij

    Hi Ravi,

    when i am trying to scroll up the listview, scroll up has been disabled and pull down refresh has been started.

    Any work workaround to solve this problem.

    • Vij

      Answering my self from the suggestions and i have tested it.

      when you use Swipe layout as a top node, you have to listen the scroll changes and enable/ disable swipe layout based on the index of the first visible item in the list view.

      class YourActivity extends AppCompatActivity implements ViewTreeObserver.OnScrollChangedListener {
      @Override
      protected void onStart() {
      super.onStart();
      mListView.getViewTreeObserver().addOnScrollChangedListener(this);
      }

      @Override
      protected void onStop() {
      super.onStop();
      mListView.getViewTreeObserver().removeOnScrollChangedListener(this);
      }

      @Override
      public void onScrollChanged() {
      if (mListView.getFirstVisiblePosition() == 0) {
      swipeRefresh.setEnabled(true);
      } else {
      swipeRefresh.setEnabled(false);
      }
      }
      }

  • Aqsa Shahid

    can we achieve horizontal scrolling through this..??

    • sujith

      Use the recyclerview for the horizontal scrolling!!

  • Im having a issue, when i am trying to scroll down, this is not updating, but is doing copies of my json listview. So is showing duplicades items. How can i fix it? (sorry for my bad english)

    • Hamza Al-Mahdi

      There is a problem with the code above, the writer forgot to clear the array before refreshing the list. You have to add movieList.clear(); in the start of onRefresh function to solve your problem.

  • Iman Borumand

    In Eclipse works?

    • iman hoshmand

      na aziz in amooozesh marboot be Studio ast

      • Iman Borumand

        merce baradar 🙂

  • Chirag Joshi

    Really This site is damn USEFUL, thanks man you owe my code all the time, BEST PART is VIDEO BEFORE CODE, your EXPLANATION ABOUT CODE

  • jonjon

    how can I parse json from multiple url? Thanks

    • jonjon

      I’m waiting for you @ravi8x:disqus

      • Can you give an example?

        • jonjon

          This is very important for me @@ravi8x:disqus

        • jonjon

          do you have an idea?
          @ravi8x:disqus

        • jonjon

          Why do not you answer? @ravi8x:disqus

  • mikamura r

    PHP Class to Generate JSON
    how I generate the JSON with the limit like your code?

    $query = mysql_query(“SELECT * FROM users”);
    $ray = array();
    while ($row = mysql_fetch_array($query)) {
    array_push($ray, array(
    “id” => $row[‘id’],
    “name” => $row[‘name’],
    “bio” => $row[‘bio’],
    ));
    }

    @ravi8x:disqus

  • You need to make two request at the same time and add the responses to array list and call adapter notifydatachanged method.

    • jonjon

      How Can I do that? I’m a beginner in Android applications

      • You need to learn basics then. Try to learn json parsing, recyclerview, recyclerview adapters.

  • Manoz

    🙂