坚持在Android中实施分页

时间:2010-12-26 20:21:23

标签: android

我正在为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

1 个答案:

答案 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;
    }
}