Im trying to parse some items in a listview and when I scroll down I want to get more products and add them to the list.
But my code doesnt do that it either refreshes it or crashes.
Any help?
Also adding a footer doesnt work either i get an classcastexception
JSONParser:
package com.lars.json;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.lars.R.drawable;
import android.R;
import android.util.Log;
/** A class to parse json data */
public class JSONParser {
// Receives a JSONObject and returns a list
public List<HashMap<String,Object>> parse(JSONObject jObject){
JSONArray jProducts = null;
try {
// Retrieves all the elements in the 'countries' array
jProducts = jObject.getJSONArray("products");
} catch (JSONException e) {
e.printStackTrace();
}
// Invoking getCountries with the array of json object
// where each json object represent a country
return getProducts(jProducts);
}
private List<HashMap<String, Object>> getProducts(JSONArray jProducts){
int productsCount = jProducts.length();
List<HashMap<String, Object>> productList = new ArrayList<HashMap<String,Object>>();
HashMap<String, Object> product = null;
// Taking each country, parses and adds to list object
for(int i=0; i<productsCount;i++){
try {
// Call getCountry with country JSON object to parse the country
product = getJSON((JSONObject)jProducts.get(i));
productList.add(product);
} catch (JSONException e) {
e.printStackTrace();
}
}
return productList;
}
// Parsing the Country JSON object
private HashMap<String, Object> getJSON(JSONObject f){
HashMap<String, Object> country = new HashMap<String, Object>();
String id = "";
String naam = "";
String status = "";
String prijs = "";
String productnum = "";
try {
String priceone = f.getString("prijsex");
id = f.getString("id");
naam = f.getString("naam");
status = f.getString("status");
prijs = "€" + priceone;
productnum = f.getString("productnum");
country.put("id", id);
country.put("naam", naam);
country.put("img", com.lars.R.drawable.tlogotrans);
country.put("prijs", prijs);
country.put("img_path", "http://www.lars.com/images/" + productnum + ".jpg");
if(Integer.parseInt(status) > 0){
country.put("status", com.lars.R.drawable.stock);
}else{
country.put("status", com.lars.R.drawable.nostock);
}
} catch (JSONException e) {
e.printStackTrace();
}
return country;
}
}
Download tasks and Listview loaders:
/** A method to download json data from url */
private String downloadUrl(String strUrl) throws IOException{
String data = "";
InputStream iStream = null;
try{
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while( ( line = br.readLine()) != null){
sb.append(line);
}
data = sb.toString();
br.close();
}catch(Exception e){
Log.d("Exception while downloading url", e.toString());
}finally{
iStream.close();
}
return data;
}
/** AsyncTask to download json data */
private class DownloadTask extends AsyncTask<String, Integer, String>{
String data = null;
@Override
protected String doInBackground(String... url) {
try{
data = downloadUrl(url[0]);
}catch(Exception e){
Log.d("Background Task",e.toString());
}
return data;
}
@Override
protected void onPostExecute(String result) {
// The parsing of the xml data is done in a non-ui thread
ListViewLoaderTask listViewLoaderTask = new ListViewLoaderTask();
Log.i("Result", result);
if(result.equals(" ")){
Log.i("No img", "No Img");
}else{
listViewLoaderTask.execute(result);
}
// Start parsing xml data
}
}
/** AsyncTask to parse json data and load ListView */
private class ListViewLoaderTask extends AsyncTask<String, Void, SimpleAdapter>{
JSONObject jObject;
private List<HashMap<String, Object>> products;
// Doing the parsing of xml data in a non-ui thread
@Override
protected SimpleAdapter doInBackground(String... strJson) {
try{
jObject = new JSONObject(strJson[0]);
JSONParser jsonpars = new JSONParser();
jsonpars.parse(jObject);
}catch(Exception e){
Log.d("JSON Exception1",e.toString());
}
// Instantiating json parser class
JSONParser jsonpars = new JSONParser();
// A list object to store the parsed countries list
try{
// Getting the parsed data as a List construct
if(set == 0){
products = jsonpars.parse(jObject);
}else{
products.addAll(jsonpars.parse(jObject));
}
}catch(Exception e){
Log.d("Exception",e.toString());
}
// Keys used in Hashmap
String[] from = { "img","naam","status","prijs"};
// Ids of views in listview_layout
int[] to = { R.id.imPThumb,R.id.tvPRName,R.id.imstock,R.id.tvPRPrijs};
// Instantiating an adapter to store each items
// R.layout.listview_layout defines the layout of each item
SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), products, R.layout.productlijstrow, from, to);
return adapter;
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
publishProgress();
Log.i("ListView Loader Task", "Update");
super.onProgressUpdate(values);
}
/** Invoked by the Android on "doInBackground" is executed */
@SuppressWarnings("unchecked")
@Override
protected void onPostExecute(SimpleAdapter adapter) {
// View v = getLayoutInflater().inflate(R.layout.footerview, null);
//list.addFooterView(v);
// Setting adapter for the listview
list.setAdapter(adapter);
if(set == 0){
list.setOnScrollListener(onAnswersScrolled);
set++;
}
list.setOnItemClickListener(onAnswerClicked);
list.setTextFilterEnabled(true);
/* list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
@SuppressWarnings("unchecked")
HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position);
Bundle extra = new Bundle();
Intent i = new Intent("com.lars.productdescription");
extra.putString("id", o.get("id"));
i.putExtras(extra);
startActivity(i);
}
});*/
for(int i=0;i<adapter.getCount();i++){
HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(i);
String imgUrl = (String) hm.get("img_path");
Log.i("imgurlonPost", imgUrl);
ImageLoaderTask imageLoaderTask = new ImageLoaderTask();
HashMap<String, Object> hmDownload = new HashMap<String, Object>();
hmDownload.put("img_path",imgUrl);
hmDownload.put("position", i);
// Starting ImageLoaderTask to download and populate image in the listview
imageLoaderTask.execute(hmDownload);
adapter.notifyDataSetChanged();
}
/* list.setOnScrollListener(new OnScrollListener(){
});*/
}
}
/** AsyncTask to download and load an image in ListView */
private class ImageLoaderTask extends AsyncTask<HashMap<String, Object>, Void, HashMap<String, Object>>{
@Override
protected HashMap<String, Object> doInBackground(HashMap<String, Object>... hm) {
InputStream iStream=null;
String imgUrl = (String) hm[0].get("img_path");
int position = (Integer) hm[0].get("position");
HashMap<String, Object> hmBitmap = new HashMap<String, Object>();
URL url;
try {
url = new URL(imgUrl);
// Creating an http connection to communicate with url
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
Log.i("imgUrl", imgUrl);
// Connecting to url
urlConnection.connect();
// Log.i("Response", urlConnection.getResponseMessage());
// Reading data from url
if(urlConnection.getResponseMessage().contains("OK")){
iStream = urlConnection.getInputStream();
// Getting Caching directory
File cacheDirectory = getBaseContext().getCacheDir();
cacheDirectory.delete();
// Temporary file to store the downloaded image
File tmpFile = new File(cacheDirectory.getPath() + "/wpta_"+position+".png");
// The FileOutputStream to the temporary file
FileOutputStream fOutStream = new FileOutputStream(tmpFile);
// Creating a bitmap from the downloaded inputstream
Bitmap b = BitmapFactory.decodeStream(iStream);
// Writing the bitmap to the temporary file as png file
b.compress(Bitmap.CompressFormat.PNG,100, fOutStream);
// Flush the FileOutputStream
fOutStream.flush();
//Close the FileOutputStream
fOutStream.close();
// Create a hashmap object to store image path and its position in the listview
// Storing the path to the temporary image file
hmBitmap.put("img",tmpFile.getPath());
// Storing the position of the image in the listview
hmBitmap.put("position",position);
// Returning the HashMap object containing the image path and position
return hmBitmap;
}else{
Log.i("nope", "nb");
String uriStr = "android.resource://" + "com.lars" + "/" + R.drawable.ic_launcher;
hmBitmap.put("img", uriStr);
hmBitmap.put("position",position);
return hmBitmap;
}
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
@SuppressWarnings("unchecked")
@Override
protected void onPostExecute(HashMap<String, Object> result) {
// Getting the path to the downloaded image
String path = (String) result.get("img");
// Getting the position of the downloaded image
int position = (Integer) result.get("position");
// Getting adapter of the listview
adapter = (SimpleAdapter ) list.getAdapter();
// Getting the hashmap object at the specified position of the listview
HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(position);
// Overwriting the existing path in the adapter
hm.put("img",path);
// Noticing listview about the dataset changes
adapter.notifyDataSetChanged();
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
publishProgress();
adapter.notifyDataSetChanged();
Log.i("Image Task", "Update");
super.onProgressUpdate(values);
}
}
private OnItemClickListener onAnswerClicked = new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
@SuppressWarnings("unchecked")
HashMap<String, String> o = (HashMap<String, String>) parent.getItemAtPosition(position);
Bundle extra = new Bundle();
Intent i = new Intent("com.lars.productdescription");
extra.putString("id", o.get("id"));
i.putExtras(extra);
startActivity(i);
}
};
private OnScrollListener onAnswersScrolled = new OnScrollListener() {
public void onScroll(AbsListView view, int first, int visibleitems, int totalitemcount) {
// TODO Auto-generated method stub
int lastInScreen = first + visibleitems;
if(lastInScreen == totalitemcount){
if(kf == 0){
Log.i("onScroll", "" + c);
Log.i("kf", "0");
String filfinal = keuze.replace(" ", "thisisaspace");
String strUrl = "http://www.lars.nl/getName.php?name=" + filfinal + "&page=" + c ;
DownloadTask downloadTask = new DownloadTask();
downloadTask.execute(strUrl);
c = c + o;
Log.i("After Scroll", "" + c);
}else{
Log.i("onScroll", "" + c);
Log.i("kf", "1");
String strUrl = "http://www.lars.nl/get.php?id=" + filter + "&page=" + c ;
DownloadTask downloadTask = new DownloadTask();
downloadTask.execute(strUrl);
c = c + o;
Log.i("After Scroll", "" + c);
}
}
}
public void onScrollStateChanged(AbsListView view, int scrollstate) {
// TODO Auto-generated method stub
}
};
}
I’d like to introduce you to CWAC-ENDLESS by non other than the brilliant mark murphy (commonsware). Not only is it a fine example of the power of putting an adapter inside another adapter, it handles all the background tasks for you as well as scrolling so that your data list may be added to very easily by following the demo
I sincerely hope this helps you as much as its helped me.