0

i'm making infinite recycleview with json.
this code works only half
i can see items loaded at first time.
but when i scroll down,
nothing happen, i guess, maybe onLoadMore() is not working.
i been edited 4hours
direct me
where should i edit?
thank you for interest in this.

MainActivity

package com.androidcss.jsonexample;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    // CONNECTION_TIMEOUT and READ_TIMEOUT are in milliseconds
    public static final int CONNECTION_TIMEOUT = 10000;
    public static final int READ_TIMEOUT = 15000;
    private RecyclerView mRVFishPrice;
    private AdapterFish mAdapter;
    protected Handler handler;
    List<DataFish> data=new ArrayList<>();

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


        //Make call to AsyncTask
        new AsyncLogin().execute();


        handler = new Handler();

        mRVFishPrice = (RecyclerView)findViewById(R.id.fishPriceList);
        mAdapter = new AdapterFish(MainActivity.this, data, mRVFishPrice);
        mRVFishPrice.setAdapter(mAdapter);
        mRVFishPrice.setLayoutManager(new     LinearLayoutManager(MainActivity.this));

        mAdapter.setOnLoadMoreListener(new AdapterFish.OnLoadMoreListener() {

            @Override
            public void onLoadMore() {

                //add progress item
                data.add(null);
                mAdapter.notifyItemInserted(data.size() - 1);

                handler.postDelayed(new Runnable() {

                    @Override
                    public void run() {

                        new AsyncLogin().execute();

                    }

                }, 2000);

                System.out.println("load");
            }

        });

    }

    private class AsyncLogin extends AsyncTask<String, String, String> {
        ProgressDialog pdLoading = new ProgressDialog(MainActivity.this);
        HttpURLConnection conn;
        URL url = null;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            //this method will be running on UI thread
            pdLoading.setMessage("\tLoading...");
            pdLoading.setCancelable(false);
            pdLoading.show();

        }

        @Override
        protected String doInBackground(String... params) {
            try {

                // Enter URL address where your json file resides
                // Even you can make call to php file which returns json data
                url = new URL("http://10.0.2.2/test/example.json");

            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return e.toString();
            }
            try {

                // Setup HttpURLConnection class to send and receive data from php and mysql
                conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(READ_TIMEOUT);
                conn.setConnectTimeout(CONNECTION_TIMEOUT);
                conn.setRequestMethod("GET");

                // setDoOutput to true as we recieve data from json file
                conn.setDoOutput(true);

            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                return e1.toString();
            }

            try {

                int response_code = conn.getResponseCode();

                // Check if successful connection made
                if (response_code == HttpURLConnection.HTTP_OK) {

                    // Read data sent from server
                    InputStream input = conn.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
                    StringBuilder result = new StringBuilder();
                    String line;

                    while ((line = reader.readLine()) != null) {
                        result.append(line);
                    }

                    // Pass data to onPostExecute method
                    return (result.toString());

                } else {

                    return ("unsuccessful");
                }

            } catch (IOException e) {
                e.printStackTrace();
                return e.toString();
            } finally {
                conn.disconnect();
            }


        }

        @Override
        protected void onPostExecute(String result) {

            //this method will be running on UI thread

            pdLoading.dismiss();
            List<DataFish> data=new ArrayList<>();

            pdLoading.dismiss();
            try {

                JSONArray jArray = new JSONArray(result);

                // Extract data from json and store into ArrayList as class objects
                for(int i=0;i<jArray.length();i++){
                    JSONObject json_data = jArray.getJSONObject(i);
                    DataFish fishData = new DataFish();
                    fishData.fishImage= json_data.getString("fish_img");
                    fishData.fishName= json_data.getString("fish_name");
                    fishData.catName= json_data.getString("cat_name");
                    fishData.sizeName= json_data.getString("size_name");
                    fishData.price= json_data.getInt("price");
                    data.add(fishData);
                }

                   // Setup and Handover data to recyclerview
                    mRVFishPrice = (RecyclerView)findViewById(R.id.fishPriceList);
                    mAdapter = new AdapterFish(MainActivity.this, data, mRVFishPrice);
                    mRVFishPrice.setAdapter(mAdapter);
                    mRVFishPrice.setLayoutManager(new LinearLayoutManager(MainActivity.this));

            } catch (JSONException e) {
                Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
            }

        }

    }
}

AdapterFish.java

package com.androidcss.jsonexample;

import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
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.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import java.util.Collections;
import java.util.List;

public class AdapterFish extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context context;
    final private Context context2 = context;
    private LayoutInflater inflater;
    List<DataFish> data= Collections.emptyList();
    DataFish current;
    int currentPos=0;



    private final int VIEW_ITEM = 1;
    private final int VIEW_PROG = 0;


    // The minimum amount of items to have below your current scroll position before loading more.
    private int visibleThreshold = 2;
    private int lastVisibleItem, totalItemCount;
    private boolean loading;
    private OnLoadMoreListener onLoadMoreListener;



    // create constructor to innitilize context and data sent from MainActivity
    public AdapterFish(Context context, List<DataFish> data, RecyclerView recyclerView){
        this.context=context;
        inflater= LayoutInflater.from(context);
        this.data=data;

        if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {

            final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);

                    totalItemCount = linearLayoutManager.getItemCount();
                    lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
                    if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                        // End has been reached
                        // Do something
                        if (onLoadMoreListener != null) {

                            onLoadMoreListener.onLoadMore();
                        }
                        loading = true;
                    }
                }
            });
        }
    }


    @Override
    public int getItemViewType(int position) {
        return data.get(position) != null ? VIEW_ITEM : VIEW_PROG;
    }


    // Inflate the layout when viewholder created
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        MyViewHolder holder;

        if (viewType == VIEW_ITEM) {

            View view = inflater.inflate(R.layout.container_fish, parent, false);
            holder = new MyViewHolder(view);

        }
        else
        {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.progressbar_item, parent, false);
            RecyclerView.ViewHolder vh = new ProgressViewHolder(v);

            return vh;
        }

    return holder;
    }

    // Bind data
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        // Get current position of item in recyclerview to bind data and assign values from list
        MyViewHolder myHolder= (MyViewHolder) holder;
        DataFish current=data.get(position);
        myHolder.textFishName.setText(current.fishName);
        myHolder.textSize.setText("Size: " + current.sizeName);
        myHolder.textType.setText("Category: " + current.catName);
        myHolder.textPrice.setText("Rs. " + current.price + "\\Kg");
        myHolder.textPrice.setTextColor(ContextCompat.getColor(context, R.color.colorAccent));

        // load image into imageview using glide
        Glide.with(context).load("http://192.168.1.7/test/images/" + current.fishImage)
            .placeholder(R.drawable.ic_img_error)
            .error(R.drawable.ic_img_error)
            .into(myHolder.ivFish);

    }

    public void setLoaded() {
        loading = false;
    }

    // return total item from List
    @Override
    public int getItemCount() {
        return data.size();
    }

    public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
        this.onLoadMoreListener = onLoadMoreListener;
    }

    public interface OnLoadMoreListener {
        void onLoadMore();
    }

    public static class ProgressViewHolder extends RecyclerView.ViewHolder {
        public ProgressBar progressBar;

        public ProgressViewHolder(View v) {
            super(v);
            progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
        }
    }


        class MyViewHolder extends RecyclerView.ViewHolder{

        TextView textFishName;
        ImageView ivFish;
        TextView textSize;
        TextView textType;
        TextView textPrice;

        // create constructor to get widget reference
        public MyViewHolder(View itemView) {
            super(itemView);
            textFishName= (TextView) itemView.findViewById(R.id.textFishName);
            ivFish= (ImageView) itemView.findViewById(R.id.ivFish);
            textSize = (TextView) itemView.findViewById(R.id.textSize);
            textType = (TextView) itemView.findViewById(R.id.textType);
            textPrice = (TextView) itemView.findViewById(R.id.textPrice);
        }

    }

}
user3662974
  • 75
  • 1
  • 3
  • 9

2 Answers2

1

I can give my own method of loading more items. You have to create your own abstract class called ScrollRecycler which extends from RecyclerView.OnScrollListener.Here it is implemantation

public abstract class ScrollRecycler extends RecyclerView.OnScrollListener {
int page = 0;
// The current offset index of data you have loaded
int startingPageIndex = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;

RecyclerView.LayoutManager mLayoutManager;

public ScrollRecycler(LinearLayoutManager layoutManager) {
    this.mLayoutManager = layoutManager;
}

public int getLastVisibleItem(int[] lastVisibleItemPositions) {
    int maxSize = 0;
    for (int i = 0; i < lastVisibleItemPositions.length; i++) {
        if (i == 0) {
            maxSize = lastVisibleItemPositions[i];
        }
        else if (lastVisibleItemPositions[i] > maxSize) {
            maxSize = lastVisibleItemPositions[i];
        }
    }
    return maxSize;
}

// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
@Override
public void onScrolled(RecyclerView view, int dx, int dy) {
    int lastVisibleItemPosition = 0;
    int totalItemCount = mLayoutManager.getItemCount();

    if (mLayoutManager instanceof StaggeredGridLayoutManager) {
        int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null);
        // get maximum element within the list
        lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);
    } else if (mLayoutManager instanceof LinearLayoutManager) {
        lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
    }
    // If the total item count is zero and the previous isn't, assume the
    // list is invalidated and should be reset back to initial state
    if (totalItemCount < previousTotalItemCount) {
        page = startingPageIndex;
        this.previousTotalItemCount = totalItemCount;
        if (totalItemCount == 0) {
            this.loading = true;
        }
    }
    // If it’s still loading, we check to see if the dataset count has
    // changed, if so we conclude it has finished loading and update the current page
    // number and total item count.
    if (loading && (totalItemCount > previousTotalItemCount)) {
        loading = false;
        previousTotalItemCount = totalItemCount;
    }
    // If it isn’t currently loading, we check to see if we have breached
    // the visibleThreshold and need to reload more data.
    // If we do need to reload some more data, we execute onLoadMore to fetch the data.
    // threshold should reflect how many total columns there are too
    int visibleThreshold = 10;
    if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
        page++;
        onLoadMore(page);
        loading = true;
    }
}
public abstract void onLoadMore(final int page);

And you have to add your abstract class to your RecyclerView not Adapter.

public class MainActivity extends AppCompatActivity {

// CONNECTION_TIMEOUT and READ_TIMEOUT are in milliseconds
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private RecyclerView mRVFishPrice;
private AdapterFish mAdapter;
protected Handler handler;
List<DataFish> data=new ArrayList<>();

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


    //Make call to AsyncTask
    new AsyncLogin().execute();


    handler = new Handler();

    mRVFishPrice = (RecyclerView)findViewById(R.id.fishPriceList);
    mAdapter = new AdapterFish(MainActivity.this, data, mRVFishPrice);
    mRVFishPrice.setAdapter(mAdapter);
    mRVFishPrice.setLayoutManager(new LinearLayoutManager(MainActivity.this));
    mRVFishPrice.addOnScrollListener(new ScrollRecycler(new LinearLayoutManager(MainActivity.this)) {
        @Override
        public void onLoadMore(int page) {
            // you can make network call to Server in order to retrive data here page is comminh
        }
    });


}

I think it will help you

dara
  • 673
  • 7
  • 12
  • @Override public void onLoadMore(int page) { // you can make network call to Server in order to retrive data here page is comminh Toast.makeText(getApplication(),"test",Toast.LENGTH_SHORT).show(); } – user3662974 Oct 06 '16 at 17:52
  • Sardor Islomov i attached like this. Toast isn't working. when i scroll down to bottom. what would be problem? =( could you help me. – user3662974 Oct 06 '16 at 18:04
  • There is problem with Toast I think you have to use MainActivity.this instead getApplication() – dara Oct 06 '16 at 18:44
  • Sardor Islomov. ScrollRecycler class i attached to MainActivity. and changed Toast to MainActivity.this. then app loading is stoping. :( help me please. sorry. – user3662974 Oct 06 '16 at 19:03
  • You implement abstract class to your mainActivity yes ? – dara Oct 06 '16 at 19:14
0

Here is my code for Fragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_all, container, false);
    ButterKnife.bind(this, view);
    fab = (FloatingActionButton) view.findViewById(R.id.fab_fragment_all);
    type = getArguments().getString("type");
    if(type.equals(Utils.TYPE_JOURNAL)){
        fab.show();
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                makeSubscribeForJournal();
            }
        });
    }else{
        fab.hide();
    }
    category_name = getArguments().getString("category_name");
    manager = new LinearLayoutManager(getContext());
    adapter = new AllAdapter(getContext(), onArticleClickListener);
    recyclerView.setLayoutManager(manager);
    recyclerView.setAdapter(adapter);
    swipe.post(new Runnable() {
        @Override
        public void run() {
            swipe.setRefreshing(true);
            makeCall(1, category_name,type);
        }
    });
    swipe.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            swipe.setRefreshing(false);
        }
    });

    recyclerView.addOnScrollListener(new ScrollRecycler(manager, type) {
        @Override
        public void onLoadMore(int page) {
            makeCall(page, category_name,type);
        }
    });
    return view;
}

Here is my ScrollRecycler abstract class which is same as yours.

public abstract class ScrollRecycler extends RecyclerView.OnScrollListener {
int page = 1;
// The current offset index of data you have loaded
int startingPageIndex = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
String type;
RecyclerView.LayoutManager mLayoutManager;

public ScrollRecycler(LinearLayoutManager layoutManager ,String type) {
    this.mLayoutManager = layoutManager;
    this.type= type;
}

public int getLastVisibleItem(int[] lastVisibleItemPositions) {
    int maxSize = 0;
    for (int i = 0; i < lastVisibleItemPositions.length; i++) {
        if (i == 0) {
            maxSize = lastVisibleItemPositions[i];
        }
        else if (lastVisibleItemPositions[i] > maxSize) {
            maxSize = lastVisibleItemPositions[i];
        }
    }
    return maxSize;
}

// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
@Override
public void onScrolled(RecyclerView view, int dx, int dy) {
    int lastVisibleItemPosition = 0;
    int totalItemCount = mLayoutManager.getItemCount();
    if(type.equals(Utils.TYPE_JOURNAL)) {
        if (dy > 0) {
            AllFragment.fab.hide();
        } else {
            AllFragment.fab.show();
        }
    }
    if (mLayoutManager instanceof StaggeredGridLayoutManager) {
        int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null);
        // get maximum element within the list
        lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);
    } else if (mLayoutManager instanceof LinearLayoutManager) {
        lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
    }
    // If the total item count is zero and the previous isn't, assume the
    // list is invalidated and should be reset back to initial state
    if (totalItemCount < previousTotalItemCount) {
        page = startingPageIndex;
        this.previousTotalItemCount = totalItemCount;
        if (totalItemCount == 0) {
            this.loading = true;
        }
    }
    // If it’s still loading, we check to see if the dataset count has
    // changed, if so we conclude it has finished loading and update the current page
    // number and total item count.
    if (loading && (totalItemCount > previousTotalItemCount)) {
        loading = false;
        previousTotalItemCount = totalItemCount;
    }
    // If it isn’t currently loading, we check to see if we have breached
    // the visibleThreshold and need to reload more data.
    // If we do need to reload some more data, we execute onLoadMore to fetch the data.
    // threshold should reflect how many total columns there are too
    int visibleThreshold = 10;
    if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
        page++;
        onLoadMore(page);
        loading = true;
    }
}
public abstract void onLoadMore(final int page);

}

dara
  • 673
  • 7
  • 12