Raghunandan Raghunandan - 6 months ago 35
Android Question

How to load data from server to listview when scrolled?

I have a listview which displays a image and a text. I want display 8 listview rows at a time downloading the data from the server. When the user scrolls the listview i need to download more more data form server and display the items in listview. I have used AsyncTask to Download data from server.

@Override
protected Void doInBackground(Void... params) {
getData();// get data first time. 8 data items.
return null;
}

@Override
protected void onPostExecute(Void result) {

super.onPostExecute(result);
pd.dismiss();
lv= (ListView) findViewById(R.id.lvn);
yt = new YouTubeAdapter(Youtube.this,msg,title,thumb);
lv.setAdapter(yt);
lv.setOnScrollListener(new EndLessScroll());

}


Get Data Code

public void getData()
{
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpGet request = new HttpGet("http://gdata.youtube.com/feeds/api/users/mbbangalore/uploads?v=2&alt=jsonc");
try
{
HttpResponse response = httpclient.execute(request);
HttpEntity resEntity = response.getEntity();
String _response=EntityUtils.toString(resEntity); // content will be consume only once

JSONObject json = new JSONObject(_response);

jsonArray = json.getJSONObject("data").getJSONArray("items");
for (int i = 0; i < 8; i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);

String title1 = jsonObject.getString("title");
title.add(title1);
String thumbUrl = jsonObject.getJSONObject("thumbnail").getString("sqDefault");
URL url1 = new URL(thumbUrl);
Bitmap bmp = BitmapFactory.decodeStream(url1.openConnection().getInputStream());
thumb.add(bmp);
String url;
try {

url = jsonObject.getJSONObject("player").getString("default");
msg.add(url);
} catch (JSONException ignore) {
}
}
}
catch(Exception e1)
{
e1.printStackTrace();
}

httpclient.getConnectionManager().shutdown();
}


Loading Data when Scrolling

class EndLessScroll implements OnScrollListener {

private int visibleThreshold = 5;
private int currentPage = 0;
private int previousTotal = 0;
private boolean loading = true;

public EndLessScroll() {
}
public EndLessScroll(int visibleThreshold) {
this.visibleThreshold = visibleThreshold;
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount)

if (lv.getLastVisiblePosition() >= lv.getCount());
{System.out.println("............................"+"first"+ firstVisibleItem+"visible"+visibleItemCount+"total"+ totalItemCount);
for (int i= totalItemCount; i < jsonArray.length(); i++) {
try
{
JSONObject jsonObject = jsonArray.getJSONObject(i);
// The title of the video
String title1 = jsonObject.getString("title");
title.add(title1);
System.out.println("title"+title);
String thumbUrl = jsonObject.getJSONObject("thumbnail").getString("sqDefault");
URL url1 = new URL(thumbUrl);
Bitmap bmp = BitmapFactory.decodeStream(url1.openConnection().getInputStream());
thumb.add(bmp);
String url;
url = jsonObject.getJSONObject("player").getString("default");
msg.add(url);
} catch (JSONException ignore) {
// url = jsonObject.getJSONObject("player").getString("default");
}
catch(Exception e)
{

}
yt.notifyDataSetChanged();
}
}
}

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


Now the Problem. I can display 8 listview rows with scroll. Imagine the server has 10000 data items. I need to display 8 items in listview at a time downloading the rest when user scrolls down. As and when user scrolls down new data should be downloaded and displayed till user is able to see the 10000th data. What's wrong with this code??.

Answer

If you don't want to use scrolling detector, Another way is to trigger download from adapter, when last item is requested from getView(), run task and append some more items to Adapter's collection. Then call notifyDataSetChanged().

UPDATE:

See demo gist here.