Stuck in implementing Pagination in Android
I am implementing pagination for ListView in Android . I am extending the BaseAdapater class for customising the ListView.
Already I have the code working fine for the Customised ListView. Below is the new requirement.
1>I am fetching 6 items from server & displaying them . Now when the user scrolls to the 6th item(end of list) , I need to call the server to fetch the next 6 items & update the Listview
I have overriden the methods
i>public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount)
ii>public void onScrollStateChanged(AbsListView view, int scrollState)
In the first response from the server, I get the total no of pages from the server & for each time I call the server , I get the current page value .
Kindly provide me the steps/sample code on how to check 开发者_StackOverflow中文版the last item of the list & update the list . The code should be iterative since I may need to call multiple times & fetch from server.
Warm Regards,
CB
Why not just download it all in the background rather than doing it every time there is a request? I have an app where I had considered doing the same thing you are doing but decided to use a background thread to do it instead.
Here is a great example of how to use threads
http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/
How I implemented it was that I retrieve the total count of records available first and then start a new thread for each "page" of records I want to retrieve.
// Create and launch the download thread
downloadThread = new DownloadThread(this);
downloadThread.start();
// Create the Handler. It will implicitly bind to the Looper
// that is internally created for this thread (since it is the UI
// thread)
handler = new Handler();
resultCount = getResultCount(search).trim();
resultsCount = Integer.parseInt(resultCount);
page = 1;
if (resultsCount > 0) {
downloadThread
.enqueueDownload(new DownloadTask(page));
}
I added my method to retrieve the records to DownloadTask.java from the example above and call it from run() and I added another public method to retrieve the results once the
I modified DownloadThread.java so that the synchronized call to task (DownloadTask) calls my method in DownloadTask >> task.run() and in finally{} I retrieve the returned results
public synchronized void enqueueDownload(final DownloadTask task) {
// Wrap DownloadTask into another Runnable to track the statistics
handler.post(new Runnable() {
@Override
public void run() {
try {
task.run();
} finally {
// register task completion
synchronized (DownloadThread.this) {
results = task.getResults();
totalCompleted++;
}
// tell the listener something has happened
signalUpdate();
}
}
});
Then I added a new method to DownloadThread.java which allows me to retrive the results from the update notification in my activity
public synchronized ArrayList<Result> getResults() {
return results;
}
For example, if there are 60 records and each page contains 6 records, I start a thread to retrieve the first 6 and then when the handleDownloadThreadUpdate() is called I populate the array with those results and call a method in my Adapter called update() that calls notifyDataSetChanged().
public void handleDownloadThreadUpdate() {
handler.post(new Runnable() {
@Override
public void run() {
for (Result res : downloadThread.getResults()) {
if (!results.contains(res)) {
results.add(intern(res));
}
}
arrayAdapter.update();
int pages = (int) Math.ceil(resultsCount / 6);
if (page < pages) {
page = page + 1;
downloadThread.enqueueDownload(new DownloadTask(page));
}
}
});
}
So it recursively downloads the pages and adds the results to my list.
One more thing I forgot to mention. I have a class called Result which holds each result that I store in an ArrayList. Just in case the results try to use too much memory I am caching them in a WeakReference HashMap... as you can see the call to intern() when it's added to the ArrayList above.
private Map<Result, WeakReference<Result>> myInternMap = new HashMap<Result, WeakReference<Result>>();
public Result intern(Result value) {
synchronized (myInternMap) {
WeakReference<Result> curRef = myInternMap.get(value);
Result curValue = ((curRef != null) ? curRef.get() : null);
if (curValue != null) {
return curValue;
}
myInternMap.put(value, new WeakReference<Result>(value));
return value;
}
}
精彩评论