bEtTy Barnes bEtTy Barnes - 5 months ago 86
Android Question

Android listview infinite scrolling using Retrofit

I need your help with my current project. The requirement is to make the listview paginated and will load other data when scrolled down just like what Facebook and Twitter apps do.

This is what I've tried so far:

MainActivity

listView.setOnScrollListener(new InfiniteScrollListener() {
public boolean onLoadMore(int page, int totalItemsCount) {
// Triggered only when new data needs to be appended to the list
// Add whatever code is needed to append new items to your AdapterView
customLoadMoreDataFromApi(page);
// or customLoadMoreDataFromApi(totalItemsCount);
return true; // ONLY if more data is actually being loaded; false otherwise.
}
});


private void getData() {
if(ConnectionDetector.hasNetworkConnection(getActivity())) {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(HOME_DOMAIN)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();

WebServices service = restAdapter.create(WebServices.class);

service.getRecords(
"1", // Row
"10", // Count
new Callback<World>() {
@Override
public void success(Som som, Response response) {
dataList = Parser.getResponseBody(response);
adapter = new SomAdapter(getActivity(), dataList);
listView.setAdapter(adapter);
}

@Override
public void failure(RetrofitError retrofitError) {
Log.e(TAG, "" + retrofitError.toString());
}
});

} else {
Toast.makeText(getActivity(),
getActivity().getResources().getString(R.string.connection_error),
Toast.LENGTH_SHORT).show();
}

}

// Append more data into the adapter
public void customLoadMoreDataFromApi(int offset) {
// This method probably sends out a network request and appends new data items to your adapter.
// Use the offset value and add it as a parameter to your API request to retrieve paginated data.
// Deserialize API response and then construct new objects to append to the adapter
getData();
moreProgress.setVisibility(View.VISIBLE);
Log.e(TAG, "MORE PROGRESS");
}


InfiniteScrollListener:

public abstract class InfiniteScrollListener implements AbsListView.OnScrollListener {

private int bufferItemCount = 10;
private int currentPage = 0;
private int itemCount = 0;
private boolean isLoading = true;

public InfiniteScrollListener(int bufferItemCount) {
this.bufferItemCount = bufferItemCount;
}

public abstract void loadMore(int page, int totalItemsCount);

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// Do Nothing
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
if (totalItemCount < itemCount) {
this.itemCount = totalItemCount;
if (totalItemCount == 0) {
this.isLoading = true; }
}

if (isLoading && (totalItemCount > itemCount)) {
isLoading = false;
itemCount = totalItemCount;
currentPage++;
}

if (!isLoading && (totalItemCount - visibleItemCount)<=(firstVisibleItem + bufferItemCount)) {
loadMore(currentPage + 1, totalItemCount);
isLoading = true;
}
}


}

This displays the the progressbar when scrolled down. This works but I also need to append to the listview the next fetched data. How am I going to do that? I need your advice as this is my first time to do pagination in Android. Thanks!

Answer

You did everything right. But instead of creating new SomAdapter, you just need to add newly fetched data to it

@Override
public void success(Som som, Response response) {
   dataList = Parser.getResponseBody(response);
   if (adapter == null) {
      adapter = new SomAdapter(getActivity(),dataList);
      listView.setAdapter(adapter);
   } else {
      adapter.addAll(dataList);
   }
}

If you make custom adapter instead of extending ArrayAdapter, make sure that your addAll method has notifyDataSetChanged.

Change getData() to take param offset and you pagination request logic.

Comments