我试图实现无限ListView
,它首先加载了10个元素,当我滚动到这10个元素的底部时,它应该加载另外10个。这就是代码I&#39写到现在:
private class ResultListScrollListener implements OnScrollListener{
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE) {
if (mResultListView.getLastVisiblePosition() >= mResultListView.getCount()-1 && mResultListView.getLastVisiblePosition()<count-1) {
page_num++;
//count is final variable=60 so that scrolling stops at 60.
Log.i("onScrollStateChanged", "last visible: "+ mResultListView.getLastVisiblePosition() + " Page num: " + page_num);
new LoadItemsAsyncTask().execute();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
}
它确实会加载更多的元素,但它会在错误的时间加载,而不是在最后一个可见位置为9,19,29 ....等时加载,它会加载不规律,比如9次加载,然后跳过19然后三次加载29.我该如何解决这个问题?这是我的LogCat输出,因此您可以看到onScrollStateChanged
被调用的时间:
07-09 12:16:06.197: I/onScrollStateChanged(27014): last visible: 9 Page num: 1
07-09 12:16:06.648: I/onScrollStateChanged(27014): last visible: 9 Page num: 2
07-09 12:16:11.122: D/dalvikvm(27014): GC_CONCURRENT freed 1069K, 26% free 3477K/4643K, paused 11ms+4ms
07-09 12:16:24.946: I/onScrollStateChanged(27014): last visible: 29 Page num: 3
07-09 12:16:25.376: I/onScrollStateChanged(27014): last visible: 29 Page num: 4
07-09 12:16:26.527: I/onScrollStateChanged(27014): last visible: 29 Page num: 5
修改
通过跟踪上一个最后一个可见位置并仅在前一个不等于当前的情况下加载项目,我才能使其正常运行。所以现在我有了
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE) {
if (mResultListView.getLastVisiblePosition() >= mResultListView.getCount()-1 && mResultListView.getLastVisiblePosition()<count-1
&& mResultListView.getLastVisiblePosition()!=last_visible) { //added this condition
page_num++;
Log.i("onScrollStateChanged", "last visible: "+ mResultListView.getLastVisiblePosition() + " Page num: " + page_num);
last_visible=mResultListView.getLastVisiblePosition();
new LoadItemsAsyncTask().execute();
}
}
}
现在我得到了正确的输出,如:
07-09 12:33:26.152: I/onScrollStateChanged(27734): last visible: 9 Page num: 1
07-09 12:33:29.735: D/dalvikvm(27734): GC_CONCURRENT freed 1092K, 26% free 3455K/4643K, paused 10ms+7ms
07-09 12:33:33.969: I/onScrollStateChanged(27734): last visible: 19 Page num: 2
07-09 12:33:43.409: I/onScrollStateChanged(27734): last visible: 29 Page num: 3
07-09 12:33:49.014: I/onScrollStateChanged(27734): last visible: 39 Page num: 4
07-09 12:33:53.979: I/onScrollStateChanged(27734): last visible: 49 Page num: 5
但我无法理解为什么没有dit就行不通。有什么解释吗?
答案 0 :(得分:0)
如果你想要一个简单的解决方案,请使用chris banes pull来刷新库
1&GT; https://github.com/chrisbanes/Android-PullToRefresh
2&GT; https://github.com/chrisbanes/ActionBar-PullToRefresh
此库中的所有列表视图都有一个onLastItemVisibleListener,您可以在其中放置代码
您还可以通过isRefreshing()检查列表是否已经刷新,以阻止列表再次加载。
答案 1 :(得分:0)
这是我的实施工作得很好
list.setOnScrollListener(new AbsListView.OnScrollListener() {
// is the number of list items (counted from the end) that should, if visible, trigger the loading process.
// If you set threshold to 0, for instance, the user has to scroll to the very end of the list in order to load more items.
int treshhold = 0;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE) {
if(isLastPageEmpty){
return;
}
if (list.getLastVisiblePosition() >= list.getCount() - 1 - treshhold) {
page++;
if(itemsArray != null) {
lastVisibleListPosition = itemsArray.size();
}
GetItemsAsync async = new GetItemsAsync();
async.execute();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
private class GetItemsAsync extends AsyncTask<Void, Void, Result> {
@Override
protected Result doInBackground(Void... params) {
// send request for new items
}
@Override
protected void onPostExecute(Result result) {
super.onPostExecute(result);
try {
if (result.status.equalsIgnoreCase("fail")) {
// show error
} else {
if(result.items.size() == 0){
// no more items
isLastPageEmpty = true;
return;
}
if (itemsArray == null) {
itemsArray = result.items;
} else {
itemsArray.addAll(result.items);
}
adapter = new ListAdapter(getActivity(), itemsArray);
list.setAdapter(adapter);
// scroll list to previous position
if(lastVisibleListPosition > 0){
list.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
list.setSelection(lastVisibleListPosition - 1); list.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}