Here is my code displaying a list that is being parsed from an html file.
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);
}
There is a lot of data coming from this (over 100 items in the array) and it's taking a while to load. I was wondering if there is a way to load 10 items at a time and use an OnScrollListener
to continue loading the data from the file? Any suggestions will be appreciated.
There appear to be many ways to accomplish running background code when you reach the end of a listview, the following snippet is what I chose to implement:
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);
}
}
}
});
As for the class AddItem, what I wanted required creating a custom array object, 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
Then I would have to iterate through the file, adding desired strings to their respect ArrayList, and combine all three lists into an ArrayList<Gift>
which is shown below.
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);
}
}
After that, all I had to do was change my adapter to extend ArrayList<Gift>
and add the following code:
public void addItems(ArrayList<Gift> newItems) {
if (null == newItems || newItems.size() <= 0) {
return;
}
if (null == finalArray) {
finalArray = new ArrayList<Gift>();
}
finalArray.addAll(newItems);
notifyDataSetChanged();
}