适用于Android ListView的无尽适配器

时间:2015-02-23 01:51:00

标签: android listview ion

我使用Ion库从服务器接收数据。我有问题,我的代码多次获取请求,所以我的列表中有数据重复。 我的适配器代码:

public class ArticleAdapter extends ArrayAdapter<Article> {

Future<List<Article>> loadingOfPrevious;

static class ArticleHolder {
    ImageView articleImage;
    TextView articleCaption;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ArticleHolder holder;
    if (convertView == null) {
        convertView = layoutInflater.inflate(R.layout.list_view_item, null);
        holder = new ArticleHolder();
        holder.articleImage = (ImageView) convertView.findViewById(R.id.articleImage);
        holder.articleCaption  = (TextView) convertView.findViewById(R.id.articleCaption);
        convertView.setTag(holder);
    } else {
        holder = (ArticleHolder) convertView.getTag();
    }
    Article article = getItem(position);

    holder.articleCaption.setText(article.getTitle());

    Ion.with(holder.articleImage)
       .placeholder(R.drawable.placeholder)
       .error(R.drawable.default_article_image)
       //.crossfade(true)
       .load(article.getImageUrl());

    // we're near the end of the list adapter, so load more items
    if (position >= getCount() - 3) {
        loadPrevious(getItem(getCount() - 1).getId());
    }

    return convertView;
}

private void loadPrevious(long id) {
    // don't attempt to load more if a load is already in progress
    if (loadingOfPrevious != null && !loadingOfPrevious.isDone() && !loadingOfPrevious.isCancelled()) {
        return;
    }
    String url = "http://example.com/rest-api/"
    url = url + "?id=" + id;
    url = url + "&count=" + 30;
    // This request loads a URL as JsonArray and invokes
    // a callback on completion.
    final String articleUrl = url;
    loadingOfLatest = Ion.with(getContext())
            .load(articleUrl)
            .as(new TypeToken<List<Article>>() {
            })
            .setCallback(new FutureCallback<List<Article>>() {
                @Override
                public void onCompleted(Exception e, List<Article> result) {
                    // this is called back onto the ui thread, no Activity.runOnUiThread or Handler.post necessary.
                    if (e != null) {
                        Toast.makeText(getContext(), "Error.", Toast.LENGTH_LONG).show();
                        return;
                    }
                    // add the article
                    if (result != null) { 
                        Collections.reverse(result);
                        for (int i = 0; i < result.size(); i++) {
                            add(result.get(i));
                        }
                        notifyDataSetChanged();
                    }
                }
            });
}

}

我认为问题在于这一部分:

// we're near the end of the list adapter, so load more items
    if (position >= getCount() - 3) {
        loadPrevious(getItem(getCount() - 1).getId());
    }

2 个答案:

答案 0 :(得分:2)

我这样做的方法是在ListView上使用OnScrollListener。当用户滚动并且firstVisibleItem + visibleItemCount接近列表限制时,启动服务器数据加载。

数据加载完成后,使用新数据更新列表适配器并调用onNotifyDataSetChanged()。然后,该列表将重新显示您的更新数据。

答案 1 :(得分:1)

你是对的!这是因为这段代码。

    if (position >= getCount() - 3) {
        loadPrevious(getItem(getCount() - 1).getId());
    }

根据您的情况,“loadPrevious()”将被调用两次。

“getView()”每次返回一个视图。因此,对于最后两项,您的条件为真,然后两次调用“loadPrevious()”。 所以改变并尝试这样

if (position >= getCount() - 2) {
    loadPrevious(getItem(getCount() - 1).getId());
}

OR

重新检查此代码

if (loadingOfPrevious != null && !loadingOfPrevious.isDone() &&     !loadingOfPrevious.isCancelled()) {
    return; 
} 
顺便说一句,我想建议尝试其他方式,比如使用库,自定义listview

Android Endless List