Reputation: 372
I am a newbie in android and I've been working around pagination with recyclercview. I am receiving my data from a server(running php) and returning it in a JSON format which brings the data in bunches like 1-10, 11-20... so on. I call notifyDataSetChanged with this. But the problem is recyclerview scrolls back to the top when retrieving more data instead of retaining the current position. How do I go about this?
When scrollbar gets to the bottom, it triggers the asynctask
AsynTask:
public class LoadRecharge extends AsyncTask<String, String, String> {
private boolean socketTimeout = false;
Context context;
public static final String TAG = "custom_message";
public AsyncResponse delegate = null;
private String server_url = "https://blockgator.com/mobile/endless.php";
public LoadRecharge(Context ctxt, AsyncResponse asyncResponse) {
delegate = asyncResponse;
context = ctxt;
}
@Override
protected String doInBackground(String... params) {
if (connectGoogle()) {
String post_data = "";
try {
URL url = new URL(server_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
post_data = URLEncoder.encode("page", "UTF-8") + "=" + URLEncoder.encode(params[0], "UTF-8");
bufferedWriter.write(post_data);
bufferedWriter.flush();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
return result;
} catch (IOException e) {
Log.e(TAG, "error: " + e.getMessage());
}
} else {
this.socketTimeout = true;
}
return null;
}
@Override
protected void onPreExecute() {
arr.add(null);
scrollAdapter.notifyItemInserted(arr.size() - 1);
}
@Override
protected void onPostExecute(String result) {
arr.remove(arr.size() - 1);
scrollAdapter.notifyItemRemoved(arr.size());
if (this.socketTimeout) {
Toast.makeText(context, "unable to connect to server", Toast.LENGTH_SHORT).show();
} else {
delegate.processFinish(result);
}
}
public boolean connectGoogle() {
try {
HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
urlc.setConnectTimeout(3000);
urlc.connect();
return (urlc.getResponseCode() == 200);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
@Override
public void processFinish(String output) {
try {
JSONObject jsonObject = new JSONObject(output);
if (jsonObject.get("status").toString().equals("success")) {
JSONArray jsonarr = jsonObject.getJSONArray("data");
String columns[] = {"id", "bill_amount", "bill_price", "variation"};
for (int i = 0; i < jsonarr.length(); i++) {
ArrayList<String> temp = new ArrayList<>();
for (String column : columns) {
temp.add(jsonarr.getJSONObject(i).getString(column));
}
arr.add(temp);
setAdapter(arr);
}
} else if (jsonObject.get("status").toString().equals("end")) {
total = "end";
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(this, "exception from json", Toast.LENGTH_LONG).show();
} catch (NullPointerException e) {
Toast.makeText(this, "Unable to connect to server...", Toast.LENGTH_LONG).show();
Toast.makeText(this, "Null from json", Toast.LENGTH_LONG).show();
}
}
public void setAdapter(ArrayList<ArrayList<String>> arr) {
recycler.setAdapter(scrollAdapter);
scrollAdapter.notifyDataSetChanged();
scrollAdapter.setLoading();
scrollAdapter.setOnItemClickListener(this);
scrollAdapter.setOnLoadMoreListener(this);
}
Upvotes: 4
Views: 2003
Reputation: 1222
In setAdapter() you dont need to do recycler.setAdapter(scrollAdapter); again, just do it at the beginning
I do something similar, but reversed, working as chat
messages.addAll(0, oldMessages);
mAdapter.notifyItemRangeInserted(0, oldMessages.size());
mAdapter.notifyItemChanged(oldMessages.size());
mAdapter.setLoaded();
Im adding the old messages of the char to the messages.
Then notifing the adapter I have updated the source
I uses the 0 to put at the beginning
Upvotes: 1
Reputation: 17844
Remove this line recycler.setAdapter(scrollAdapter);
You need to set your adapter just once either in Activity's onCreate method or Fragment's onCreateView method.
Upvotes: 4