Tutorials Android Android Lollipop Swipe to Refresh Example

Android Lollipop Swipe to Refresh Example

In the course of this tutorial, we will take a look into the new Swipe to refresh layout introduced in material design.

Android Lollipop is baked with some of the finest looking user interface widgets and UI design guidelines, and what they call it as Material Design. Some of the widgets are fine-tuned while some new of them are added to the SDK.

The Swipe to refresh layout is used to indicate user while the content of a screen is being updated. The Swipe to refresh layout was earlier introduced in Android 4.4 Kitkat and was named as SwipeRefreshLayout. Visually it was represented just below ActionBar.

Since Android Lollipop, the visual representation of the swipe to refresh layout has been changed drastically. It appears as a circular refresh animation, horizontally centered and appears right below the Toolbar. Check out official documentation for Swipe to refresh layout in Android Lollipop.

Swipe to Refresh Layout Example

In this example, we will create the sample application that downloads the data from a server feed, and displays on a ListView. It also allows the user the ability to swipe down and request for updated data from the server.

The output of this example is as the following video.


Now without wasting much of time, lets us move straight into its implementation. To implement Swipe to refresh layout, you will need the v4 support library. You can include the v4 support library to your project by adding below dependency in build.gradle file.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile "com.android.support:appcompat-v7:21.0.+"
}

Secondly, let us define the swipe to refresh layout and list view to show the feed response. Create a new layout file inside res/layout folder, name it as activity_main.xml and paste the below code snippets.

activity_main.xml

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

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>
</android.support.v4.widget.SwipeRefreshLayout>

How it works

  • The ListView is placed as a child view to SwipeRefreshLayout.
  • This allows user the ability to show the loading spinner when user swipes the ListView edge. All the functionality of displaying loading bar is encapsulated inside SwipeRefreshLayout class.
  • When user swipes down, the OnRefreshListener events gets fired. You can handle this event to write the logic for downloading or refreshing data.
  • Note that, once data is downloaded, user has to manually call setRefreshing(false) to hide the refresh spinner.

Let us now initialize the SwipeRefreshLayout and ListView from activity and write the logic to download data from server.

In this example we are downloading data form server and parsing JSON response before we rendering it on the ListView. Please refer Android Networking Tutorial for understanding more on this code.

MainActivity.java

public class MainActivity extends ActionBarActivity {

    private ListView mListView = null;
    private ArrayAdapter mAdapter = null;
    private SwipeRefreshLayout mSwipeRefreshLayout = null;

    private String[] feedList = null;
    private String feedUrl = "http://stacktips.com/api/get_category_posts/?dev=1&slug=android";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        mListView = (ListView) findViewById(R.id.listView);

        //Start Downloading data
        new DownloadFilesTask().execute(feedUrl);

        //Initialize swipe to refresh view
        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //Refreshing data on server
                new DownloadFilesTask().execute(feedUrl);
            }
        });
    }


    private void updateList() {
        ArrayAdapter mAdapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, feedList);
        mListView.setAdapter(mAdapter);

        if (mSwipeRefreshLayout.isRefreshing()) {
            mSwipeRefreshLayout.setRefreshing(false);
        }
    }


    private class DownloadFilesTask extends AsyncTask<String, Void, Void> {

        @Override
        protected void onProgressUpdate(Void... values) {
        }

        @Override
        protected void onPostExecute(Void result) {
            if (null != feedList) {
                updateList();
            }
        }

        @Override
        protected Void doInBackground(String... params) {
            // getting JSON string from URL
            JSONObject json = getJSONFromUrl(params[0]);

            //parsing json data
            parseJson(json);
            return null;
        }
    }

    public JSONObject getJSONFromUrl(String url) {
        InputStream is = null;
        JSONObject jObj = null;
        String json = null;

        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();

            BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();

            jObj = new JSONObject(json);

        } catch (Exception e) {
            Log.e("Error", "Error parsing data " + e.toString());
        }
        return jObj;
    }


    public void parseJson(JSONObject json) {
        try {
            if (json.getString("status").equalsIgnoreCase("ok")) {
                JSONArray posts = json.getJSONArray("posts");

                feedList = new String[posts.length()];
                for (int i = 0; i < posts.length(); i++) {
                    JSONObject post = (JSONObject) posts.getJSONObject(i);
                    feedList[i] = post.getString("title");
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}
[download url=”https://github.com/npanigrahy/Android-Lollipop-Swipe-to-Refresh”]
Total
0
Shares
guest
7 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
JavaTechig
JavaTechig
7 years ago

You must retain the scroll position of the list. And use listView.scrollToPosition() method to scroll to the position where user left previously.

Eric
Eric
7 years ago

Works fine except for the fact that when I refresh, it duplicates the already existing list items

Eric
Eric
7 years ago

Works except for the fact that when I refresh, it duplicates the already existing list items

Nilanchala Panigrahy
Nilanchala Panigrahy
7 years ago
Reply to  Eric

You have to careful check while making the request for same page. Placing a database logic is preferable.

zicaros
zicaros
7 years ago

thx u sir

Susheel
Susheel
6 years ago

package com.impresa.labs;

import java.io.BufferedReader;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Locale;

import android.app.Activity;

import android.app.ProgressDialog;

import android.content.Intent;

import android.content.pm.PackageManager;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Color;

import android.graphics.drawable.BitmapDrawable;

import android.graphics.drawable.ColorDrawable;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.os.Environment;

import android.provider.MediaStore;

import android.util.Log;

import android.view.View;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.TextView;

import android.widget.Toast;

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.support.v4.app.ListFragment;

import android.support.v4.widget.SwipeRefreshLayout;

import android.view.LayoutInflater;

import android.view.MenuInflater;

import android.view.MenuItem;

import android.view.View;

import android.view.ViewGroup;

import info.androidhive.listviewfeed.adapter.FeedListAdapter;

import info.androidhive.listviewfeed.app.AppController;

import info.androidhive.listviewfeed.data.FeedItem;

import java.io.UnsupportedEncodingException;

import java.util.ArrayList;

import java.util.List;

import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.impl.client.DefaultHttpClient;

import org.json.JSONArray;

import org.json.JSONException;

import org.json.JSONObject;

import android.annotation.SuppressLint;

import android.app.Activity;

import android.content.Intent;

import android.graphics.Color;

import android.graphics.drawable.ColorDrawable;

import android.os.Bundle;

import android.view.Menu;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ListView;

import info.androidhive.listviewfeed.adapter.FeedListAdapter;

import com.android.volley.Cache;

import com.android.volley.Cache.Entry;

import com.android.volley.Request.Method;

import com.android.volley.Response;

import com.android.volley.VolleyError;

import com.android.volley.VolleyLog;

import com.android.volley.toolbox.JsonObjectRequest;

import com.android.volley.toolbox.NetworkImageView;

import com.impresa.labs.MainActivity;

import com.impresa.labs.R;

public class Stories extends Fragment {

private static final String TAG = Stories.class.getSimpleName();

private ProgressDialog pDialog;

private ListView listView;

private FeedListAdapter listAdapter;

private List feedItems;

private String URL_FEED = “http://jokesnstuffs.com/projectx/onlystory.php”;

private static final String TAG_NAME = “name”;

private static final String TAG_TIMESTAMP = “timestamp”;

private static final String TAG_STATUS = “txtStatusMsg”;

private Button update, feedback;

private SwipeRefreshLayout mSwipeRefreshLayout = null;

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

setHasOptionsMenu(true);

View rootView = inflater.inflate(R.layout.fragment_top_rated,

container, false);

listView = (ListView) rootView.findViewById(R.id.list);

rootView.findViewById(R.id.allow);

feedItems = new ArrayList();

listAdapter = new FeedListAdapter(getActivity(), feedItems);

listView.setOnItemClickListener(new Click2());

listView.setAdapter(listAdapter);

update = (Button) rootView.findViewById(R.id.deny3);

new DownloadFilesTask().execute(URL_FEED);

//Initialize swipe to refresh view

mSwipeRefreshLayout = (SwipeRefreshLayout)rootView.findViewById(R.id.swipeRefreshLayout);

mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {

@Override

public void onRefresh() {

//Refreshing data on server

new DownloadFilesTask().execute(URL_FEED);

}

});

update.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

Intent nxt = new Intent(getActivity(), Feedback.class);

startActivity(nxt);

}

});

feedback = (Button) rootView.findViewById(R.id.deny3);

update.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

Intent nxt = new Intent(getActivity(), Feedback.class);

startActivity(nxt);

}

});

Cache cache = AppController.getInstance().getRequestQueue().getCache();

Entry entry = cache.get(URL_FEED);

if (entry != null) {

// fetch the data from cache

try {

String data = new String(entry.data, “UTF-8”);

try {

parseJsonFeed(new JSONObject(data));

} catch (JSONException e) {

e.printStackTrace();

}

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

} else {

// making fresh volley request and getting json

JsonObjectRequest jsonReq = new JsonObjectRequest(Method.GET,

URL_FEED, null, new Response.Listener() {

@Override

public void onResponse(JSONObject response) {

VolleyLog.d(TAG, “Response: ” + response.toString());

if (response != null) {

parseJsonFeed(response);

}

}

}, new Response.ErrorListener() {

@Override

public void onErrorResponse(VolleyError error) {

VolleyLog.d(TAG, “Error: ” + error.getMessage());

}

});

// Adding request to volley request queue

AppController.getInstance().addToRequestQueue(jsonReq);

}

return rootView;

}

private void updateList() {

ArrayAdapter mAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, feedItems);

listView.setAdapter(mAdapter);

if (mSwipeRefreshLayout.isRefreshing()) {

mSwipeRefreshLayout.setRefreshing(false);

}

}

private class DownloadFilesTask extends AsyncTask {

@Override

protected void onProgressUpdate(Void… values) {

}

@Override

protected void onPostExecute(Void result) {

if (null != feedItems) {

updateList();

}

}

@Override

protected Void doInBackground(String… params) {

// getting JSON string from URL

JSONObject json = getJSONFromUrl(params[0]);

//parsing json data

parseJsonFeed(json);

return null;

}

}

public JSONObject getJSONFromUrl(String url) {

InputStream is = null;

JSONObject jObj = null;

String json = null;

try {

DefaultHttpClient httpClient = new DefaultHttpClient();

HttpPost httpPost = new HttpPost(url);

HttpResponse httpResponse = httpClient.execute(httpPost);

HttpEntity httpEntity = httpResponse.getEntity();

is = httpEntity.getContent();

BufferedReader reader = new BufferedReader(new InputStreamReader(is, “iso-8859-1”), 8);

StringBuilder sb = new StringBuilder();

String line = null;

while ((line = reader.readLine()) != null) {

sb.append(line + “n”);

}

is.close();

json = sb.toString();

jObj = new JSONObject(json);

} catch (Exception e) {

Log.e(“Error”, “Error parsing data ” + e.toString());

}

return jObj;

}

private void parseJsonFeed(JSONObject response) {

try {

JSONArray feedArray = response.getJSONArray(“contacts”);

for (int i = 0; i < feedArray.length(); i++) {

JSONObject feedObj = (JSONObject) feedArray.get(i);

FeedItem item = new FeedItem();

item.setName(feedObj.getString("name"));

item.setStatus(feedObj.getString("status"));

item.setTimeStamp(feedObj.getString("timeStamp"));

feedItems.add(item);

}

// notify data changes to list adapater

listAdapter.notifyDataSetChanged();

} catch (JSONException e) {

e.printStackTrace();

}

}

private class Click2 implements ListView.OnItemClickListener {

@Override

public void onItemClick(AdapterView parent, View view, int position,

long id) {

String name = ((TextView) view.findViewById(R.id.name)).getText()

.toString();

String status = ((TextView) view.findViewById(R.id.txtStatusMsg))

.getText().toString();

String timestamp = ((TextView) view.findViewById(R.id.timestamp))

.getText().toString();

// String bitmap =

// ((Movie)feedItems.get(position)).getThumbnailUrl();

Intent in = new Intent(getActivity(), SingleActivity2.class);

in.putExtra(TAG_NAME, name);

in.putExtra(TAG_TIMESTAMP, timestamp);

in.putExtra(TAG_STATUS, status);

// in.putExtra(“images”, bitmap);

startActivity(in);

}

}

@Override

public void onDestroy() {

super.onDestroy();

hidePDialog();

}

private void hidePDialog() {

if (pDialog != null) {

pDialog.dismiss();

pDialog = null;

}

}

}

Susheel
Susheel
6 years ago

can you please check its not working sir error in doing in background method
parseJsonFeed(json);

package com.impresa.labs;

import java.io.BufferedReader;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Locale;

import android.app.Activity;

import android.app.ProgressDialog;

import android.content.Intent;

import android.content.pm.PackageManager;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Color;

import android.graphics.drawable.BitmapDrawable;

import android.graphics.drawable.ColorDrawable;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.os.Environment;

import android.provider.MediaStore;

import android.util.Log;

import android.view.View;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.TextView;

import android.widget.Toast;

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.support.v4.app.ListFragment;

import android.support.v4.widget.SwipeRefreshLayout;

import android.view.LayoutInflater;

import android.view.MenuInflater;

import android.view.MenuItem;

import android.view.View;

import android.view.ViewGroup;

import info.androidhive.listviewfeed.adapter.FeedListAdapter;

import info.androidhive.listviewfeed.app.AppController;

import info.androidhive.listviewfeed.data.FeedItem;

import java.io.UnsupportedEncodingException;

import java.util.ArrayList;

import java.util.List;

import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.impl.client.DefaultHttpClient;

import org.json.JSONArray;

import org.json.JSONException;

import org.json.JSONObject;

import android.annotation.SuppressLint;

import android.app.Activity;

import android.content.Intent;

import android.graphics.Color;

import android.graphics.drawable.ColorDrawable;

import android.os.Bundle;

import android.view.Menu;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ListView;

import info.androidhive.listviewfeed.adapter.FeedListAdapter;

import com.android.volley.Cache;

import com.android.volley.Cache.Entry;

import com.android.volley.Request.Method;

import com.android.volley.Response;

import com.android.volley.VolleyError;

import com.android.volley.VolleyLog;

import com.android.volley.toolbox.JsonObjectRequest;

import com.android.volley.toolbox.NetworkImageView;

import com.impresa.labs.MainActivity;

import com.impresa.labs.R;

public class Stories extends Fragment {

private static final String TAG = Stories.class.getSimpleName();

private ProgressDialog pDialog;

private ListView listView;

private FeedListAdapter listAdapter;

private List feedItems;

private String URL_FEED = “http://jokesnstuffs.com/projectx/onlystory.php”;

private static final String TAG_NAME = “name”;

private static final String TAG_TIMESTAMP = “timestamp”;

private static final String TAG_STATUS = “txtStatusMsg”;

private Button update, feedback;

private SwipeRefreshLayout mSwipeRefreshLayout = null;

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

setHasOptionsMenu(true);

View rootView = inflater.inflate(R.layout.fragment_top_rated,

container, false);

listView = (ListView) rootView.findViewById(R.id.list);

rootView.findViewById(R.id.allow);

feedItems = new ArrayList();

listAdapter = new FeedListAdapter(getActivity(), feedItems);

listView.setOnItemClickListener(new Click2());

listView.setAdapter(listAdapter);

update = (Button) rootView.findViewById(R.id.deny3);

new DownloadFilesTask().execute(URL_FEED);

//Initialize swipe to refresh view

mSwipeRefreshLayout = (SwipeRefreshLayout)rootView.findViewById(R.id.swipeRefreshLayout);

mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {

@Override

public void onRefresh() {

//Refreshing data on server

new DownloadFilesTask().execute(URL_FEED);

}

});

update.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

Intent nxt = new Intent(getActivity(), Feedback.class);

startActivity(nxt);

}

});

feedback = (Button) rootView.findViewById(R.id.deny3);

update.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

Intent nxt = new Intent(getActivity(), Feedback.class);

startActivity(nxt);

}

});

Cache cache = AppController.getInstance().getRequestQueue().getCache();

Entry entry = cache.get(URL_FEED);

if (entry != null) {

// fetch the data from cache

try {

String data = new String(entry.data, “UTF-8”);

try {

parseJsonFeed(new JSONObject(data));

} catch (JSONException e) {

e.printStackTrace();

}

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

} else {

// making fresh volley request and getting json

JsonObjectRequest jsonReq = new JsonObjectRequest(Method.GET,

URL_FEED, null, new Response.Listener() {

@Override

public void onResponse(JSONObject response) {

VolleyLog.d(TAG, “Response: ” + response.toString());

if (response != null) {

parseJsonFeed(response);

}

}

}, new Response.ErrorListener() {

@Override

public void onErrorResponse(VolleyError error) {

VolleyLog.d(TAG, “Error: ” + error.getMessage());

}

});

// Adding request to volley request queue

AppController.getInstance().addToRequestQueue(jsonReq);

}

return rootView;

}

private void updateList() {

ArrayAdapter mAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, feedItems);

listView.setAdapter(mAdapter);

if (mSwipeRefreshLayout.isRefreshing()) {

mSwipeRefreshLayout.setRefreshing(false);

}

}

private class DownloadFilesTask extends AsyncTask {

@Override

protected void onProgressUpdate(Void… values) {

}

@Override

protected void onPostExecute(Void result) {

if (null != feedItems) {

updateList();

}

}

@Override

protected Void doInBackground(String… params) {

// getting JSON string from URL

JSONObject json = getJSONFromUrl(params[0]);

//parsing json data

parseJsonFeed(json);

return null;

}

}

public JSONObject getJSONFromUrl(String url) {

InputStream is = null;

JSONObject jObj = null;

String json = null;

try {

DefaultHttpClient httpClient = new DefaultHttpClient();

HttpPost httpPost = new HttpPost(url);

HttpResponse httpResponse = httpClient.execute(httpPost);

HttpEntity httpEntity = httpResponse.getEntity();

is = httpEntity.getContent();

BufferedReader reader = new BufferedReader(new InputStreamReader(is, “iso-8859-1”), 8);

StringBuilder sb = new StringBuilder();

String line = null;

while ((line = reader.readLine()) != null) {

sb.append(line + “n”);

}

is.close();

json = sb.toString();

jObj = new JSONObject(json);

} catch (Exception e) {

Log.e(“Error”, “Error parsing data ” + e.toString());

}

return jObj;

}

private void parseJsonFeed(JSONObject response) {

try {

JSONArray feedArray = response.getJSONArray(“contacts”);

for (int i = 0; i < feedArray.length(); i++) {

JSONObject feedObj = (JSONObject) feedArray.get(i);

FeedItem item = new FeedItem();

item.setName(feedObj.getString("name"));

item.setStatus(feedObj.getString("status"));

item.setTimeStamp(feedObj.getString("timeStamp"));

feedItems.add(item);

}

// notify data changes to list adapater

listAdapter.notifyDataSetChanged();

} catch (JSONException e) {

e.printStackTrace();

}

}

private class Click2 implements ListView.OnItemClickListener {

@Override

public void onItemClick(AdapterView parent, View view, int position,

long id) {

String name = ((TextView) view.findViewById(R.id.name)).getText()

.toString();

String status = ((TextView) view.findViewById(R.id.txtStatusMsg))

.getText().toString();

String timestamp = ((TextView) view.findViewById(R.id.timestamp))

.getText().toString();

// String bitmap =

// ((Movie)feedItems.get(position)).getThumbnailUrl();

Intent in = new Intent(getActivity(), SingleActivity2.class);

in.putExtra(TAG_NAME, name);

in.putExtra(TAG_TIMESTAMP, timestamp);

in.putExtra(TAG_STATUS, status);

// in.putExtra(“images”, bitmap);

startActivity(in);

}

}

@Override

public void onDestroy() {

super.onDestroy();

hidePDialog();

}

private void hidePDialog() {

if (pDialog != null) {

pDialog.dismiss();

pDialog = null;

}

}

}

Previous Post
Android Tutorials

Android RelativeLayout Example

Next Post
Android Tutorials

Android TextView Example

Related Posts
By clicking “Allow All”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. Cookie Notice
Allow All
7
0
Would love your thoughts, please comment.x
()
x