Again because of so many queries I am writing this android feed example tutorial. Recently I published Android Custom ListView with Images using RecyclerView and Volley. And in feedback many people asked that how to add more item on scroll to the list.
If you are having about 1000 or more items then downloading it once from the server would take a lots of time. And downloading all items at once is not a good idea.
That is why we should create a feed. So in this tutorial we will display some items and on scroll the items will be downloaded and added.
Android Feed – Video
You can see this video to know what actually we will be creating in this tutorial.
Now if you want to learn how to create this then lets begin our project.
Creating Server Side Database and Scripts for our Android Feed
- Data will come from server. And for this demonstration I am using Hostinger’s free hosting as my server.
- The first thing you need is a database from where you will fetch the data.
- This is my database you can create the same database or you can also change your database according to your need.
- As you can see I have 9 records in my table. I will show 3 records at once and when will user reach bottom by scrolling I will load 3 more records.
- Now the first thing we need is a script to connect to the database. Create a script named dbConnect.php and write the following code.
1 2 3 4 5 6 7 8 9 |
<?php define('HOST','mysql.hostinger.in'); define('USER','u502452270_andro'); define('PASS','belal_123'); define('DB','u502452270_andro'); $con = mysqli_connect(HOST,USER,PASS,DB) or die('Unable to Connect'); |
- No need to explain the above given code. We have used it in almost every tutorial I published.
- Now we will create the main script that will give us the data for our feed. Create a new script feed.php and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?php //Getting the page number which is to be displayed $page = $_GET['page']; //Initially we show the data from 1st row that means the 0th row $start = 0; //Limit is 3 that means we will show 3 items at once $limit = 3; //Importing the database connection require_once('dbConnect.php'); //Counting the total item available in the database $total = mysqli_num_rows(mysqli_query($con, "SELECT id from feed ")); //We can go atmost to page number total/limit $page_limit = $total/$limit; //If the page number is more than the limit we cannot show anything if($page<=$page_limit){ //Calculating start for every given page number $start = ($page - 1) * $limit; //SQL query to fetch data of a range $sql = "SELECT * from feed limit $start, $limit"; //Getting result $result = mysqli_query($con,$sql); //Adding results to an array $res = array(); while($row = mysqli_fetch_array($result)){ array_push($res, array( "name"=>$row['name'], "publisher"=>$row['publisher'], "image"=>$row['image']) ); } //Displaying the array in json format echo json_encode($res); }else{ echo "over"; } |
- While executing this script I have to pass a get variable. So for my case the URL is
http://www.simplifiedcoding.16mb.com/feed/feed.php?page=1
- If you would go to the above URL you will get a JSON string as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[ { "name":"Antman", "publisher":"Marvel", "image":"http:\/\/simplifiedcoding.16mb.com\/feed\/antman.jpg" }, { "name":"Batman", "publisher":"DC", "image":"http:\/\/simplifiedcoding.16mb.com\/feed\/batman.jpg" }, { "name":"Captain America", "publisher":"Marvel", "image":"http:\/\/simplifiedcoding.16mb.com\/feed\/captainamerica.jpg" } ] |
- We will change the page=2, page=3 to get the next items. If you would go to the above URL you will get 3 values for our android feed. You can also use my URL for this project. But it would be good if you create your own.
- Now we will move ahead to android part.
Creating an Android Feed Project
- Create a new android project in android studio. I have named this android feed project as MyFeed.
- Now the first thing you should do is add the following dependencies to your build.gradle file and sync the project.
1 2 3 4 5 6 7 8 9 10 |
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.mcxiaoke.volley:library-aar:1.0.0' compile 'com.android.support:recyclerview-v7:+' compile 'com.android.support:cardview-v7:+' } |
- So here we have added volley, recyclerview and cardview. Now add internet permission to your manifest file.
1 2 3 |
<uses-permission android:name="android.permission.INTERNET"/> |
- First we will create a class to declare some important constants. So create a class named Config.java and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package net.simplifiedcoding.myfeed; /** * Created by Belal on 12/5/2015. */ public class Config { //Data URL public static final String DATA_URL = "http://simplifiedcoding.16mb.com/feed/feed.php?page="; //JSON TAGS public static final String TAG_IMAGE_URL = "image"; public static final String TAG_NAME = "name"; public static final String TAG_PUBLISHER = "publisher"; } |
- To load the images I am using NetworkImageView. And for this we need to create a Custom Volley Request. So we will use the same code we used in Google Login Tutorial to Load Profile Picture.
- Create a new class named CustomVolleyRequest.java and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
package net.simplifiedcoding.myfeed; import android.content.Context; import android.graphics.Bitmap; import android.support.v4.util.LruCache; import com.android.volley.Cache; import com.android.volley.Network; import com.android.volley.RequestQueue; import com.android.volley.toolbox.BasicNetwork; import com.android.volley.toolbox.DiskBasedCache; import com.android.volley.toolbox.HurlStack; import com.android.volley.toolbox.ImageLoader; /** * Created by Belal on 12/5/2015. */ public class CustomVolleyRequest { private static CustomVolleyRequest customVolleyRequest; private static Context context; private RequestQueue requestQueue; private ImageLoader imageLoader; private CustomVolleyRequest(Context context) { this.context = context; this.requestQueue = getRequestQueue(); imageLoader = new ImageLoader(requestQueue, new ImageLoader.ImageCache() { private final LruCache<String, Bitmap> cache = new LruCache<String, Bitmap>(20); @Override public Bitmap getBitmap(String url) { return cache.get(url); } @Override public void putBitmap(String url, Bitmap bitmap) { cache.put(url, bitmap); } }); } public static synchronized CustomVolleyRequest getInstance(Context context) { if (customVolleyRequest == null) { customVolleyRequest = new CustomVolleyRequest(context); } return customVolleyRequest; } public RequestQueue getRequestQueue() { if (requestQueue == null) { Cache cache = new DiskBasedCache(context.getCacheDir(), 10 * 1024 * 1024); Network network = new BasicNetwork(new HurlStack()); requestQueue = new RequestQueue(cache, network); requestQueue.start(); } return requestQueue; } public ImageLoader getImageLoader() { return imageLoader; } } |
- Inside activity_main.xml create a RecyclerView and a ProgressBar to show our android feed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@dimen/activity_vertical_margin"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" /> <ProgressBar android:id="@+id/progressBar1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" /> </RelativeLayout> |
- Now we need to create layout for our list. The list I have created looks like
- For our list we need to create the above layout. So inside the layout folder create a .xml file named superheroes_list.xml and write the following code to create the above given layout.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:padding="@dimen/activity_horizontal_margin" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <com.android.volley.toolbox.NetworkImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageViewHero" /> <TableLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TableRow> <TextView android:text="Name" android:paddingRight="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/textViewName" android:textStyle="bold" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </TableRow> <TableRow> <TextView android:text="Publisher" android:paddingRight="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/textViewPublisher" android:textStyle="bold" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </TableRow> </TableLayout> </LinearLayout> </android.support.v7.widget.CardView> </RelativeLayout> |
- Now to store the list items we will create a class. So create a class named SuperHero.java and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
package net.simplifiedcoding.myfeed; /** * Created by Belal on 12/5/2015. */ public class SuperHero { //Data Variables private String imageUrl; private String name; private String publisher; //Getters and Setters public String getImageUrl() { return imageUrl; } public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPublisher() { return publisher; } public void setPublisher(String publisher) { this.publisher = publisher; } } |
- To display the items in RecyclerView we need an adapter. So create one more class named CardAdapter.java and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
package net.simplifiedcoding.myfeed; import android.content.Context; import android.media.Image; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.TextView; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.NetworkImageView; import org.w3c.dom.Text; import java.util.ArrayList; import java.util.List; /** * Created by Belal on 11/9/2015. */ public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> { //Imageloader to load image private ImageLoader imageLoader; private Context context; //List to store all superheroes List<SuperHero> superHeroes; //Constructor of this class public CardAdapter(List<SuperHero> superHeroes, Context context){ super(); //Getting all superheroes this.superHeroes = superHeroes; this.context = context; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.superheroes_list, parent, false); ViewHolder viewHolder = new ViewHolder(v); return viewHolder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { //Getting the particular item from the list SuperHero superHero = superHeroes.get(position); //Loading image from url imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader(); imageLoader.get(superHero.getImageUrl(), ImageLoader.getImageListener(holder.imageView, R.drawable.image, android.R.drawable.ic_dialog_alert)); //Showing data on the views holder.imageView.setImageUrl(superHero.getImageUrl(), imageLoader); holder.textViewName.setText(superHero.getName()); holder.textViewPublisher.setText(superHero.getPublisher()); } @Override public int getItemCount() { return superHeroes.size(); } class ViewHolder extends RecyclerView.ViewHolder{ //Views public NetworkImageView imageView; public TextView textViewName; public TextView textViewPublisher; //Initializing Views public ViewHolder(View itemView) { super(itemView); imageView = (NetworkImageView) itemView.findViewById(R.id.imageViewHero); textViewName = (TextView) itemView.findViewById(R.id.textViewName); textViewPublisher = (TextView) itemView.findViewById(R.id.textViewPublisher); } } } |
- Finally come to MainActivity.java and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
package net.simplifiedcoding.myfeed; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.ProgressBar; import android.widget.Toast; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonArrayRequest; import com.android.volley.toolbox.Volley; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity implements RecyclerView.OnScrollChangeListener { //Creating a List of superheroes private List<SuperHero> listSuperHeroes; //Creating Views private RecyclerView recyclerView; private RecyclerView.LayoutManager layoutManager; private RecyclerView.Adapter adapter; //Volley Request Queue private RequestQueue requestQueue; //The request counter to send ?page=1, ?page=2 requests private int requestCount = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Initializing Views recyclerView = (RecyclerView) findViewById(R.id.recyclerView); recyclerView.setHasFixedSize(true); layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); //Initializing our superheroes list listSuperHeroes = new ArrayList<>(); requestQueue = Volley.newRequestQueue(this); //Calling method to get data to fetch data getData(); //Adding an scroll change listener to recyclerview recyclerView.setOnScrollChangeListener(this); //initializing our adapter adapter = new CardAdapter(listSuperHeroes, this); //Adding adapter to recyclerview recyclerView.setAdapter(adapter); } //Request to get json from server we are passing an integer here //This integer will used to specify the page number for the request ?page = requestcount //This method would return a JsonArrayRequest that will be added to the request queue private JsonArrayRequest getDataFromServer(int requestCount) { //Initializing ProgressBar final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar1); //Displaying Progressbar progressBar.setVisibility(View.VISIBLE); setProgressBarIndeterminateVisibility(true); //JsonArrayRequest of volley JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Config.DATA_URL + String.valueOf(requestCount), new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { //Calling method parseData to parse the json response parseData(response); //Hiding the progressbar progressBar.setVisibility(View.GONE); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { progressBar.setVisibility(View.GONE); //If an error occurs that means end of the list has reached Toast.makeText(MainActivity.this, "No More Items Available", Toast.LENGTH_SHORT).show(); } }); //Returning the request return jsonArrayRequest; } //This method will get data from the web api private void getData() { //Adding the method to the queue by calling the method getDataFromServer requestQueue.add(getDataFromServer(requestCount)); //Incrementing the request counter requestCount++; } //This method will parse json data private void parseData(JSONArray array) { for (int i = 0; i < array.length(); i++) { //Creating the superhero object SuperHero superHero = new SuperHero(); JSONObject json = null; try { //Getting json json = array.getJSONObject(i); //Adding data to the superhero object superHero.setImageUrl(json.getString(Config.TAG_IMAGE_URL)); superHero.setName(json.getString(Config.TAG_NAME)); superHero.setPublisher(json.getString(Config.TAG_PUBLISHER)); } catch (JSONException e) { e.printStackTrace(); } //Adding the superhero object to the list listSuperHeroes.add(superHero); } //Notifying the adapter that data has been added or changed adapter.notifyDataSetChanged(); } //This method would check that the recyclerview scroll has reached the bottom or not private boolean isLastItemDisplaying(RecyclerView recyclerView) { if (recyclerView.getAdapter().getItemCount() != 0) { int lastVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition(); if (lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1) return true; } return false; } //Overriden method to detect scrolling @Override public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { //Ifscrolled at last then if (isLastItemDisplaying(recyclerView)) { //Calling the method getdata again getData(); } } } |
- Now run your application and you will see the following output.
- Bingo! Our android feed application is working fine. If you are having troubles or getting errors; you can get my project from GitHub Repository from below.
[sociallocker id=1372] Get Android Feed Example from GitHub [/sociallocker]
So thats all for this android feed tutorial friends. Please support us and give your feedback with your comments. Thank You 🙂