【问题标题】:Load ListView data when user scrolls用户滚动时加载 ListView 数据
【发布时间】:2014-04-30 22:28:40
【问题描述】:

这是我的代码,显示了一个从 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 继续从文件中加载数据?任何建议将不胜感激。

【问题讨论】:

    标签: android android-listview onscrolllistener


    【解决方案1】:

    不幸的是,我以前没有使用过这种方法,但是当列表滚动到最底部时如何加载例如 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 个元素的List,您需要创建新的Adapter

    【讨论】:

      【解决方案2】:

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

      来自 GSON 文档的示例:

      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();
          }
      }
      

      每当您达到 10 时,我都会添加额外的调用 listAdapter.notifyDataSetChanged() // ON MAIN THREAD。显然还有其他方法可以组织代码。

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

      【讨论】:

        【解决方案3】:

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

        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&lt;Gift&gt;,如下所示。

        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&lt;Gift&gt; 并添加以下代码:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-03-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多