我正在为Android中的ListView实现分页。我正在扩展BaseAdapater类以自定义ListView。
我已经使代码适用于Customized ListView。 以下是新要求。
1>我从服务器&中获取6项显示它们。现在,当用户滚动到第6项(列表末尾)时,我需要调用服务器来获取接下来的6个项目&更新Listview
我已经覆盖了方法
i> public void onScroll(AbsListView视图,int firstVisibleItem,int visibleItemCount,int totalItemCount)
ii> public void onScrollStateChanged(AbsListView view,int scrollState)
在服务器的第一个响应中,我从服务器获取了总页数。每次我调用服务器时,都会获得当前页面值。
请向我提供有关如何检查列表的最后一项的步骤/示例代码。更新列表。代码应该是迭代的,因为我可能需要多次调用&从服务器获取。
温暖的问候,
CB
答案 0 :(得分:1)
为什么不在后台下载所有内容而不是每次有请求时都这样做?我有一个应用程序,我曾考虑做同样的事情,但决定使用后台线程代替。
以下是如何使用线程的一个很好的例子
http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/
我是如何实现它的,我首先检索可用记录的总数,然后为我想要检索的记录的每个“页面”启动一个新线程。
// 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));
}
我添加了我的方法从上面的例子中检索DownloadTask.java的记录并从run()调用它,并且我添加了另一个公共方法来检索结果
我修改了DownloadThread.java,以便同步调用任务(DownloadTask)在DownloadTask>>中调用我的方法。 task.run()和finally {}我检索返回的结果
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();
}
}
});
然后我为DownloadThread.java添加了一个新方法,它允许我从我的活动中的更新通知中检索结果
public synchronized ArrayList<Result> getResults() {
return results;
}
例如,如果有60条记录,每页包含6条记录,我启动一个线程来检索前6条,然后当调用handleDownloadThreadUpdate()时,我用这些结果填充数组并调用我的适配器中的方法调用notify()调用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));
}
}
});
}
因此,它递归下载页面并将结果添加到我的列表中。
我还忘了提一件事。我有一个名为Result的类,它保存我存储在ArrayList中的每个结果。为了防止结果尝试使用太多内存,我将它们缓存在WeakReference HashMap中......因为当它被添加到上面的ArrayList时你可以看到对intern()的调用。
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;
}
}