Android Feed Example using PHP, MySQL and Volley

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 VolleyAnd 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.
android feed database
Android Feed – Database
  • 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.

  • 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.

  • 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.

  • 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.

  • So here we have added volley, recyclerview and cardview. Now add internet permission to your manifest file.

  • First we will create a class to declare some important constants. So create a class named Config.java and write the following code.

  • 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.

  • Inside activity_main.xml create a RecyclerView and a ProgressBar to show our android feed.

  • Now we need to create layout for our list. The list I have created looks like
android feed
Android Feed
  • 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.

  • Now to store the list items we will create a class. So create a class named SuperHero.java and write the following code.

  • To display the items in RecyclerView we need an adapter. So create one more class named CardAdapter.java and write the following code.

  • Finally come to MainActivity.java and write the following code.

  • Now run your application and you will see the following output.
android feed
Android Feed
  • 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.

So thats all for this android feed tutorial friends. Please support us and give your feedback with your comments. Thank You 🙂

116 thoughts on “Android Feed Example using PHP, MySQL and Volley”

  1. Hi Belal,
    very nice tutorial 😉
    Please, is the condition API 23?
    If not, I have a problem elsewhere.
    If yes, how to achieve this for minimum API 19?? Or just 21, 22 for Lollipop…

    Reply
    • Great tutorial mate.

      for api less than 21/23, following Belal’s earlier comment I used RecyclerView.OnScrollListener such that on my MainActivity’s onCreate it looked like this:

      if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
      recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
      @Override
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
      super.onScrolled(recyclerView, dx, dy);
      //Ifscrolled at last then
      if (isLastItemDisplaying(recyclerView)) {
      //Calling the method getdata again
      getData();
      }
      }
      });
      } else {
      recyclerView.setOnScrollChangeListener( new RecyclerView.OnScrollChangeListener() {
      @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();
      }
      }
      });
      }

      Worked for me under API 16 :).

      Reply
  2. Can U give in detail how to handle ItemOnClick selection (to perform) some task based on the ItemSelected (position) for lower API (ex 17,18,19)?

    Reply
  3. this project i can’t run in Android 4.4 Kikat version. i already set the minSdkVersion 19 , but it still cannot work in Android 4.4 Kikat version. It will show the app has been stopped when i run the project. how solve it? thanks

    Reply
  4. I am encountering a problem in this method, see I have employed this method to display the status and posts feed for a social app that I am developing and the problem I am facing is the FOR LOOP while parsing json array is causing to display atleast two items at the most. It is not displaying anything if the database contains only one set of items for json array (Probably for the 0 index of the array). I have trid playing with for loop for a while but to no avail. Can you suggest anything? Much thanks.

    Reply
  5. Folks, I am having a problem with the CardAdapter.java file. It says “cannot resolve symbol image”
    For the following code: “imageView, R.drawable.image”

    Can someone help?

    Reply
  6. Belal, please disregard my previous inquiry, I forgot to put a picture in the drawable folder. Man you are great – you are helping me in my carrer. Than you and be bless

    Reply
  7. Belal,

    I am still having a lot of problem with adding an onClicklistener. I added to the CardAdapter.java file. But I am having the following error:
    “Non-static field ‘name’ can not be referenced from static context”.
    How would you solve this? Any help would be appreciated.

    Reply
  8. I am using latest sdk eclipse but still can’t get the result. please help me. I try to follow your instruction but it not work. I see the red line under OnScrollChangeListener.

    Reply
  9. Hii thanks for the tutorial it working fine but im having an problem if there are 10 elements it shows three pages and displays only 9 elements but not showing last tenth element . any fix for it ????

    Reply
  10. This tutorial has been really helpful to me so I thought I should contribute my solution to those using lower SDK. Don’t implement the RecyclerView.OnScrollChangeListener

    1. REPLACE recyclerView.setOnScrollChangeListener(this); with recyclerView.addOnScrollListener(rVOnScrollListener);

    2. CREATE THE METHOD rVOnScrollListener() LIKE THIS
    private RecyclerView.OnScrollListener rVOnScrollListener = new RecyclerView.OnScrollListener(){
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView,
    int newState) {
    super.onScrollStateChanged(recyclerView, newState);
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    super.onScrolled(recyclerView, dx, dy);
    if (isLastItemDisplaying(myRecyclerView)) {
    //Calling the method getdata again
    getData();
    }

    }
    };

    I HOPE THIS HELPS SOMEONE.

    Reply
  11. Big tutorial an Extrem NICE i like and i need it.

    But my problems is i use Fragments.

    how can i use the onCreat step for my onCreateView
    ist dificult for me to construckt this for fragments.
    mybe a simpel step i can use it.

    thx for Help
    and sorry for my english

    Reply
  12. java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

    i am getting this error and at implements RecyclerView.OnScrollChangeListener i am getting error that class require min sdk23 current is 16.
    How to resolve it Belal?

    Reply
  13. Hi, thx for good tutorial.

    In your tutorial, if you have 11 datas in table in database you can get only 3 pages without 2 data.
    When you input one more data, then all data come out.

    How can I load all data although only 1 or 2 data is left.

    Reply
  14. Information:Gradle tasks [:app:generateDebugSources, :app:generateDebugAndroidTestSources, :app:assembleDebug]
    :app:preBuild UP-TO-DATE
    :app:preDebugBuild UP-TO-DATE
    :app:checkDebugManifest
    :app:preReleaseBuild UP-TO-DATE
    :volley:compileLint
    :volley:copyReleaseLint UP-TO-DATE
    :volley:mergeReleaseProguardFiles UP-TO-DATE
    :volley:preBuild UP-TO-DATE
    :volley:preReleaseBuild UP-TO-DATE
    :volley:checkReleaseManifest
    :volley:prepareReleaseDependencies
    :volley:compileReleaseAidl UP-TO-DATE
    :volley:compileReleaseRenderscript UP-TO-DATE
    :volley:generateReleaseBuildConfig UP-TO-DATE
    :volley:generateReleaseAssets UP-TO-DATE
    :volley:mergeReleaseAssets UP-TO-DATE
    :volley:generateReleaseResValues UP-TO-DATE
    :volley:generateReleaseResources UP-TO-DATE
    :volley:packageReleaseResources UP-TO-DATE
    :volley:processReleaseManifest UP-TO-DATE
    :volley:processReleaseResources UP-TO-DATE
    :volley:generateReleaseSources UP-TO-DATE
    :volley:processReleaseJavaRes UP-TO-DATE
    :volley:compileReleaseJavaWithJavac UP-TO-DATE
    :volley:packageReleaseJar UP-TO-DATE
    :volley:compileReleaseNdk UP-TO-DATE
    :volley:packageReleaseJniLibs UP-TO-DATE
    :volley:packageReleaseLocalJar UP-TO-DATE
    :volley:packageReleaseRenderscript UP-TO-DATE
    :volley:bundleRelease UP-TO-DATE
    :app:prepareComAndroidSupportAppcompatV72311Library UP-TO-DATE
    :app:prepareComAndroidSupportCardviewV72311Library UP-TO-DATE
    :app:prepareComAndroidSupportDesign2311Library UP-TO-DATE
    :app:prepareComAndroidSupportRecyclerviewV72311Library UP-TO-DATE
    :app:prepareComAndroidSupportSupportV42311Library UP-TO-DATE
    :app:prepareComMcxiaokeVolleyLibraryAar100Library UP-TO-DATE
    :app:prepareListviewwwVolleyUnspecifiedLibrary UP-TO-DATE
    :app:prepareDebugDependencies
    :app:compileDebugAidl UP-TO-DATE
    :app:compileDebugRenderscript UP-TO-DATE
    :app:generateDebugBuildConfig UP-TO-DATE
    :app:generateDebugAssets UP-TO-DATE
    :app:mergeDebugAssets UP-TO-DATE
    :app:generateDebugResValues UP-TO-DATE
    :app:generateDebugResources UP-TO-DATE
    :app:mergeDebugResources UP-TO-DATE
    :app:processDebugManifest UP-TO-DATE
    :app:processDebugResources UP-TO-DATE
    :app:generateDebugSources UP-TO-DATE
    :app:preDebugAndroidTestBuild UP-TO-DATE
    :app:prepareDebugAndroidTestDependencies
    :app:compileDebugAndroidTestAidl UP-TO-DATE
    :app:processDebugAndroidTestManifest UP-TO-DATE
    :app:compileDebugAndroidTestRenderscript UP-TO-DATE
    :app:generateDebugAndroidTestBuildConfig UP-TO-DATE
    :app:generateDebugAndroidTestAssets UP-TO-DATE
    :app:mergeDebugAndroidTestAssets UP-TO-DATE
    :app:generateDebugAndroidTestResValues UP-TO-DATE
    :app:generateDebugAndroidTestResources UP-TO-DATE
    :app:mergeDebugAndroidTestResources UP-TO-DATE
    :app:processDebugAndroidTestResources UP-TO-DATE
    :app:generateDebugAndroidTestSources UP-TO-DATE
    :app:processDebugJavaRes UP-TO-DATE
    :app:compileDebugJavaWithJavac UP-TO-DATE
    :app:compileDebugNdk UP-TO-DATE
    :app:compileDebugSources UP-TO-DATE
    :app:preDexDebug UP-TO-DATE
    :app:dexDebug
    UNEXPECTED TOP-LEVEL EXCEPTION:
    com.android.dex.DexException: Multiple dex files define Lcom/android/volley/VolleyError;
    at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:579)
    at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:535)
    at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:517)
    at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:164)
    at com.android.dx.merge.DexMerger.merge(DexMerger.java:188)
    at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:504)
    at com.android.dx.command.dexer.Main.runMonoDex(Main.java:334)
    at com.android.dx.command.dexer.Main.run(Main.java:277)
    at com.android.dx.command.dexer.Main.main(Main.java:245)
    at com.android.dx.command.Main.main(Main.java:106)
    Error:Execution failed for task ‘:app:dexDebug’.
    > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process ‘command ‘C:\Program Files\Java\jdk1.7.0_79\bin\java.exe” finished with non-zero exit value 2
    Information:BUILD FAILED
    Information:Total time: 3.894 secs
    Information:1 error
    Information:0 warnings
    Information:See complete output in console

    Reply
  15. What a great tutorial ! Unfortunate datas won’t show and the progress bar keep running over and over on my screen… any idea ?

    Reply
  16. Great tutorial bro. but I just want to suggest you in feed.php you use if($page<=$page_limit) which is give error if the page url is odd number cause the rest json value will not appear. instead of that you can use this
    if (!$page $page_limit)

    Reply
  17. Great tutorial bro. but I just want to suggest you in feed.php you use $pagelimit= $total/$limit which is give error if the page url is odd number cause the value will not round example 5:3= 1,666 which is if the page 2 it will not pass the if($page<=$page_limit) . instead of that you can use this $page_limit = round($total/$limit, 0, PHP_ROUND_HALF_UP); so the value will be round number

    Reply
    • Your answer didn’t work for me if I had to display a certain amount of items instead of a number of items dividable by 3.
      To fix it simply use the ceil function on the number, so change ” $page_limit = $total/$limit; ” to ” $page_limit = ceil($total/$limit); ”

      For example, your solution worked if I had to display 5-8-11-… items but not if there were 7-10-13-… items
      Using ceil works for both amount of items, so it’s a little bit better to use 🙂

      Reply
        • change $total = mysqli_num_rows(mysqli_query($con, “SELECT id from feed “)); to $total = mysqli_num_rows(mysqli_query($con, “SELECT id from feed ORDER BY id DESC “));

          Reply
          • Scratch that,

            change “$sql = “SELECT * from feed limit $start, $limit”;” to “$sql = “SELECT * from feed limit $start, $limit ORDER BY id DESC”;”

  18. Whit this example, can I use a click listener, that when i click in a item open a new activity, and how ?
    Thanks!! and sorry for my english…

    Reply
  19. Hello, Please how do i implement this same code on a fragment activity?

    Here is my code:

    public class AllpostsFragment extends Fragment implements RecyclerView.OnScrollChangeListener {

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

    //Creating a List of superheroes
    private List postlists;

    //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;

    public static AllpostsFragment newInstance() {
    AllpostsFragment fragment = new AllpostsFragment();
    fragment.setRetainInstance(true);
    return fragment;
    }

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

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_allposts, container, false);

    }

    @Override
    public void onViewCreated(LayoutInflater inflater, View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    // Inflate the layout for this fragment
    View rootView = inflater.inflate(R.layout.fragment_allposts, container, false);
    //Initializing Views
    RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
    recyclerView.setHasFixedSize(true);
    LinearLayoutManager llm = new LinearLayoutManager(getActivity());
    llm.setOrientation(LinearLayoutManager.VERTICAL);
    //if (listitems.size() > 0 & recyclerView != null) {
    // recyclerView.setAdapter(new MyAdapter(listitems));
    //
    //recyclerView.setLayoutManager(llm);

    //Initializing our superheroes list
    postlists = 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(postlists, 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() {
    @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(AllpostsFragment.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
    Posts_list postlist = new Posts_list();
    JSONObject json = null;
    try {
    //Getting json
    json = array.getJSONObject(i);

    //Adding data to the superhero object
    postlist.setImageUrl(json.getString(Config.TAG_IMAGE_URL));
    postlist.setTitle(json.getString(Config.TAG_NAME));
    postlist.setPostedby(json.getString(Config.TAG_POSTEDBY));
    } catch (JSONException e) {
    e.printStackTrace();
    }
    //Adding the superhero object to the list
    postlists.add(postlist);
    }

    //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();
    }
    }

    }

    Reply
  20. Hi. So when I run the code I get a message saying E/Surface: getSlotFromBufferLocked: unknown buffer 0xa9f03c70. The app launches but the feed and progress bar do not show at all. Its just a blank white screen. I’m confused as to what could be causing this problem. Any suggestions?

    Reply
  21. Hi Belal,
    It was very great tutorial.
    When I click on any image it should display the image and details on new Activity, Can you please help me with it.
    How could I do that?

    Reply
  22. hello
    Thank you from your training. I got a full run
    But it’s a problem:
    When I want to give replies to a request filter end are added to the list

    Reply
  23. Hi sir this tutorial is great it those work for me so far, but i just want to know how can i add current user to the uploaded image in the feed wall, please could you give me a solution whenever you have some spare time?…

    thanks.

    Reply
  24. Hi guys.

    I get this error when trying to execute my project

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplication2/com.example.myapplication2.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method ‘int java.lang.String.hashCode()’ on a null object reference.

    The code in my Main Activity and other classes is as above in the tutorial and so are my layouts

    Could you please assist me on how to solve this.

    Any help would be greatly appreciated.

    Thank you

    Reply
  25. It didn’t work. Sometimes app crashes or it executes saying No More Items Available. My PHP script is working fine but the app isn’t running I directly imported the app from github.

    Reply
  26. I am trying to use this for Android Kitkat Api 19 but i having same error.
    Even i had go through all the helps even from Comments section. Please tell me how to use in Kitkat.

    Error : Caused by: java.lang.ClassNotFoundException: Didn’t find class “XXX” on path: “XXX”

    Reply
  27. Hi Belal !

    I have a problen on my CardAdapter.java with this line :
    imageLoader.get(superHero.getImageUrl(), ImageLoader.getImageListener(holder.imageView, R.drawable.image, android.R.drawable.ic_dialog_alert));

    R.drawable.image : the word image is in red and I don’t know why…

    Thank you !

    Reply
  28. Hi Belal, thanks for the tutorial,please do one on itemOnClick, may be an extension of this one,where by if you click an item, you open it and can perform additional actions

    Reply
  29. Can U give in detail how to impliment ItemOnClick selection to perform some task based on the ItemSelected (position)?i need it plz tell me as soon as possible.

    Reply
  30. hey dude, awesome tutorial.

    i’m a little bit stuck/confused

    i don’t know where to the dbConnect.php & feed.php scripts go

    some insight would be great.

    thanks in advance ^_^

    Reply
  31. hey comrade i want to ask you a question how i make this feed refresh every time i enter a new query to the database
    this program read and refresh the data that are already entered before the initiation of the android app feed,apk if i entered new data it doesn’t appear unless i restart the whole application please helpout a comrade

    Reply
  32. on feed.php change

    else{
    echo “over”;
    }

    into

    else
    {
    $nextLimit = $total – ($limit * ($page – 1));
    $nextStart = ($page – 1) * $limit;
    if($nextLimit$row2[‘name’],
    “publisher”=>$row2[‘publisher’],
    “image”=>$row2[‘image’])
    );
    }
    echo json_encode($res2);
    }
    }

    the result will be if the number of rows is not divisible by the limit. on the last page it will show all that is not shown.
    for example if you have 10 rows in database and the limit is 3, on feed.php?page=4 it will not show anything but if u use this code it will show the last remaining row on feed.php?page=4

    Hope it helps

    Reply
  33. x code copy above this is the one

    else
    {
    $nextLimit = $total – ($limit * ($page – 1));
    $nextStart = ($page – 1) * $limit;
    if($nextLimit$row2[‘name’],
    “publisher”=>$row2[‘publisher’],
    “image”=>$row2[‘image’])
    );
    }
    echo json_encode($res2);
    }
    }

    Reply
  34. Thanks for awesome tutorial……………
    Please tell me one thing May i use this code in Fragment in the place of Activity

    Reply
  35. Again Thanks For the Great Tutorial Sir please tell me one thing
    how to view item details in next page and it is also dymamic…….
    PLEASE PLEASE PLEASE HELP

    Reply
  36. Consider if i have 4,5,7,8….. items in database then how should i show all data.First few page is loading properly but in last page one i am getting error.How should i resolve this?
    Help Me….!!!

    Reply
  37. Excellent coding..
    Below is my contribution to support lower android versions.
    Complete extract of MainActivity

    package net.simplifiedcoding.myfeed;

    import android.os.Build;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    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 {

    //Creating a List of superheroes
    private List 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);
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    super.onScrolled(recyclerView, dx, dy);
    //Ifscrolled at last then
    if (isLastItemDisplaying(recyclerView)) {
    //Calling the method getdata again
    getData();
    }
    }
    });
    } else {
    recyclerView.setOnScrollChangeListener(new RecyclerView.OnScrollChangeListener() {

    @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();
    }
    }
    });
    }

    //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() {
    @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;
    }

    }

    Reply
  38. If images are repeating on fast scroll, then add below overrides in CardAdapter.java

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

    @Override
    public int getItemViewType(int position) {
    return position;
    }

    Reply
  39. hii pls i ma having an error from the PHP and I followed the tutorial well. it says :-
    error: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘-3, 3’ at line 1
    pls help out

    Reply
  40. Man, thank you for this tutorial! I was able to make it work following your steps. But now I need this implementation in fragment, not in activity. Can you please direct me somehow?

    I extended it as a separate fragment class as
    public class FrontPage extends Fragment implements RecyclerView.OnScrollChangeListener{ … }
    functions from OnCreate I put in OnCreateView, and so on, but it still do not work..

    Can not resolve progressbar at:
    final ProgressBar progressBar = (ProgressBar) root.findViewById(R.id.progressBar1);
    where root is view object defined in oncreateview..

    Can you please help me?

    Reply
  41. Hi
    Do you know create layout table , Consists of two pages , The first page will be displayed table , and second page will be for add , delete and update ??

    Reply
  42. Dear sir,

    Many thnks for our tutorial
    BTW, mine is listview, not a recycler view,
    and would you guide me how to implement it to listview?
    Thanks!!!!

    Reply
  43. In pagination https://www.simplifiedcoding.net/android-feed-example-using-php-mysql-volley/ is perfect but

    [
    {
    “feed_id”: “11”,
    “regi_id”: “33”,
    “regi_name”: “Ankita Trevedi”,
    “regi_image”: “http://webbleu.biz/project/p2p/upload/user_image/IMG-20170111-WA0002_14841590408371495451492.jpg”,
    “feed_content”: “Website designing logo”,
    “feed_images”: [
    {
    “image”: “http://webbleu.biz/project/p2p/upload/feed/1495539788_International-valentine’s day (26)_&_d73b8f9c-ddb4-41d6-9009-e1beb481fac1.jpg”
    }
    ]
    },
    {
    “feed_id”: “10”,
    “regi_id”: “33”,
    “regi_name”: “Ankita Trevedi”,
    “regi_image”: “http://webbleu.biz/project/p2p/upload/user_image/IMG-20170111-WA0002_14841590408371495451492.jpg”,
    “feed_content”: “Pizza time start now”,
    “feed_images”: [
    {
    “image”: “http://webbleu.biz/project/p2p/upload/feed/1495539749_International-pizza_&_0b1cf675-e6bd-4ee9-a45b-202af0886e36.jpg”
    }
    ]
    }
    ] in this api pagination is not working….pl help me

    Reply
  44. On running, this is the error: Could not find class ‘android.graphics.drawable.RippleDrawable’, referenced from method android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering. App does not crash but shows a progressdialog then displays ‘no more items to show’.

    Reply
  45. hi belal, what type and what collation of image on database?
    because I can’t load image from my database, but I can read name and publisher from my database.

    Reply
  46. Hi
    Thanks for the awesome tutorial
    Can you help me to convert this to layout based response
    eg: if post type is image include on layout
    if video include video layout
    if text include text layout

    pls help me

    Reply
  47. Error:Execution failed for task ‘:app:transformClassesWithJarMergingForDebug’.
    > com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: android/support/v4/content/res/TypedArrayUtils.class

    Hello i have this error and i cant find solution. Please help me.

    Reply
  48. hi…….I need create MCQ app use volley with Pagination
    need to data view group radio button
    can you give to me simple example
    how to do this

    Reply
  49. There is an error in the code.

    First page – 3 data’s.
    Second Page – 3 data’s
    Third Page – 2 data’s.

    The issue is, data will be displayed perfectly for First and the second page. However, no data will be displayed for third page, until the page contains a count of 3 data’s in it.

    Reply

Leave a Comment