用户滚动时加载ListView数据

时间:2014-04-30 22:28:40

标签: android android-listview onscrolllistener

这是我的代码,显示了从html文件中解析的列表。

private class getItemDesc extends AsyncTask<Void, Void, Void> {

    private ArrayList<String> descArray;

    @Override
    protected Void doInBackground(Void... arg0) {
        try {
            File file = new File(dir, getString(R.string.html_file));
            descArray = new ArrayList<String>();
            FileInputStream in = new FileInputStream(file);
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    in, "UTF-8"));
            String line;
            while ((line = br.readLine()) != null) {
                Document doc = Jsoup.parse(line);
                Elements descs = doc.select("p");
                for (Element desc : descs) {
                    descArray.add(desc.text());
                }
            }
            in.close();
            br.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    @Override
    protected void onPostExecute(Void v) {
        MyAdapter mAdapter = new MyAdapter(getApplicationContext(),
            R.layout.list_layout, descArray);
        listView.setAdapter(mAdapter);
    }

有很多数据来自此(数组中超过100个项目)并且需要一段时间才能加载。我想知道是否有办法一次加载10个项目并使用OnScrollListener继续加载文件中的数据?任何建议将不胜感激。

3 个答案:

答案 0 :(得分:0)

不幸的是我之前没有使用过这种方法,但是当列表滚动到最底层时如何加载例如10个元素。它可以通过简单地重新安装适配器来完成,但是存在一个有效的问题。但在我看来,10个元素可以做到这一点。

lv = (ListView)findViewById(R.id.list_view);
adapter = new CustomAdaper(this ,/* List of elements*/);
lv.setAdapter(adapter);
lv.setOnScrollListener(new OnScrollListener() {
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, 
        int visibleItemCount, int totalItemCount) {
        //Check if the last view is visible
        if (++firstVisibleItem + visibleItemCount > totalItemCount) {
            adapter = new CustomAdapter(getApplicationContext() , /*UpdateYourListData*/)
            lv.setAdapter(adapter);
        }
    }
});

基本上,当ListView到达最低点时,如果当前+10个元素的Adapter,则需要创建新的List

答案 1 :(得分:0)

我会使用来自GSON或JacksonJSON的Streaming Parser。

来自GSON docs的示例:

JsonStreamParser parser = new JsonStreamParser(br);  // br is your BufferedReader()
JsonElement element;
synchronized (parser) {  // synchronize on an object shared by threads
    if (parser.hasNext()) {
       element = parser.next();
    }
}

我会在listAdapter.notifyDataSetChanged()上添加额外的内容,只要你点击10就可以在主线上进行调用。显然还有其他方法可以组织代码。

我有一个完整的分页示例here

答案 2 :(得分:0)

当您到达列表视图的末尾时,似乎有很多方法可以完成运行后台代码,以下代码段是我选择实现的:

lv.setOnScrollListener(new OnScrollListener() {

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        int threshold = 1;
        int count = lv.getCount();
        if (scrollState == SCROLL_STATE_IDLE) {
            if (lv.getLastVisiblePosition() >= count - threshold) {
                items = (AddItems) new AddItems().execute(count);
            }
        }
    }
});

对于AddItem类,我想要创建一个自定义数组对象,Gift()

public class Gift {
    private String descs;
    private String itemName;
    private String price;
    private String imageUrl;

    public Gift() {
    }

    public Gift(String p, String i, String d, String u) {
        this.descs = d;
        this.itemName = i;
        this.price = p;
        this.imageUrl = u;
    }

    public String getDetails() {
        return descs;
    }

    public void setDetails(String details) {
        this.descs = details;
    }
} // You get the idea

然后我将不得不遍历文件,将所需的字符串添加到他们尊重的ArrayList中,并将所有三个列表组合成ArrayList<Gift>,如下所示。

private class AddItems extends AsyncTask<Integer, Void, ArrayList<Gift>> {

    @Override
    protected ArrayList<Gift> doInBackground(Integer... integer) {
        try {
            amountArray = new ArrayList<String>();
            itemArray = new ArrayList<String>();
            descArray = new ArrayList<String>();
            imageUrls = new ArrayList<String>();
            finalArray = new ArrayList<Gift>();
            File file = new File(Ids.dir, getString(R.string.html_file));
            FileInputStream in = new FileInputStream(file);
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    in, "UTF-8"));
            String line;
            int itemNumber = 0;
            while ((line = br.readLine()) != null) {
                Document doc = Jsoup.parse(line);
                Elements titles = doc.select("h4[class=title]");
                Elements amounts = doc.select("div[class=price]");
                Elements descs = doc.select("p");
                Elements urls = doc.select("img[class=gallery-image]");
                for (Element price : amounts) {
                    itemNumber++;
                    amountArray.add(price.text());
                }
                for (Element title : titles) {
                    itemArray.add(title.text());
                }
                for (Element desc : descs) {
                    descArray.add(desc.text());
                }
                for (Element url : urls) {
                    imageUrls.add(url.attr("src"));
                }

                // totalShowing is a final integer with a value of 10
                // which only iterates through 10 objects plus 
                // integer[0], which is the total number of items 
                // shown in the listview.
                if (itemNumber == totalShowing + integer[0] + 1) {
                    break;
                }
            }
            in.close();
            br.close();
            finalArray = new ArrayList<Gift>();

            //  Only add to finalArray the items after position integer[0]
            //  so we don't add items we've already added
            for (int i = integer[0]; i < amountArray.size(); i++) {
                finalArray.add(new Gift(amountArray.get(i), itemArray
                        .get(i), descArray.get(i), imageUrls.get(i)));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return finalArray;
    }

    @Override
    protected void onPostExecute(ArrayList<Gift> result) {
        super.onPostExecute(result);
        da.addItems(result);
    }
}

之后,我所要做的就是更改我的适配器以扩展ArrayList<Gift>并添加以下代码:

public void addItems(ArrayList<Gift> newItems) {
    if (null == newItems || newItems.size() <= 0) {
        return;
    }
    if (null == finalArray) {
        finalArray = new ArrayList<Gift>();
    }
    finalArray.addAll(newItems);
    notifyDataSetChanged();
}