Navid Abutorab
Navid Abutorab

Reputation: 1787

android -BaseAdapter doesn't add new items to listView

I don't know why my listView doesn't add new items .

this is the code :

   ListAdapter ladap;

    private class GetContacts AsyncTask<Void, Void,ArrayList<HashMap<String, String>>> {    
    @Override
    protected Void doInBackground(Void... arg0) {
        Spots_tab1_json sh = new Spots_tab1_json();
        String jsonStr = sh.makeServiceCall(url + page, Spots_tab1_json.GET);

        ArrayList<HashMap<String, String>> dataC = new ArrayList<HashMap<String, String>>();

        if (jsonStr != null) {
            try {
                JSONObject jsonObj = new JSONObject(jsonStr);
                contacts = jsonObj.getJSONArray(TAG_CONTACTS);

                    for (int i = 0; i < contacts.length(); i++) {
                    JSONObject c = contacts.getJSONObject(i);
                    String id = new String(c.getString("id").getBytes("ISO-8859-1"), "UTF-8");
                    String dates = new String(c.getString("dates").getBytes("ISO-8859-1"), "UTF-8");
                    String price = new String(c.getString("gheymat").getBytes("ISO-8859-1"), "UTF-8");
                    HashMap<String, String> contact = new HashMap<String, String>();
                    contact.put("id", id);
                    contact.put("dates", dates);
                    contact.put("price", price);
                    dataC.add(contact);
                }
                }
            } catch (JSONException e) {
                goterr = true;
            } catch (UnsupportedEncodingException e) {
                goterr = true;
            }
        } else {
            goterr = true;
        }
        return dataC;
    }

    @Override
    protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
        super.onPostExecute(result);
        if (!isCancelled() && goterr == false) {
            if(ladap==null){
                ladap=new ListAdapter(MainActivity.this,result);
                lv.setAdapter(ladap);
            }else{
                ladap.addAll(result);
                ladap.notifyDataSetChanged();
            }

    }
}


    public class ListAdapter extends BaseAdapter {
    Activity activity;
    public ArrayList<HashMap<String, String>> list;

    public ListAdapter(Activity activity,ArrayList<HashMap<String, String>> list) {
        super();
        this.activity = (Activity) activity;
        this.list = list;
    }

    public void addAll(ArrayList<HashMap<String, String>> result) {
        Log.v("this",result.size()+" resultsize");
        this.list = result;
        notifyDataSetChanged();
    }

    public int getCount() {
        return contactList.size();
    }

    public Object getItem(int position) {
        return contactList.get(position);
    }

    public long getItemId(int arg0) {
        return 0;
    }

    private class ViewHolder {
        TextView title,price;
        ImageView img ; 
        //RelativeLayout rl; 
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        LayoutInflater inflater = activity.getLayoutInflater();
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.item, null);
            holder = new ViewHolder();
            holder.title = (TextView) convertView.findViewById(R.id.title);
            holder.price = (TextView) convertView.findViewById(R.id.price);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

            item = contactList.get(position);
            holder.price.setText(item.get("price"));
        return convertView;
    }
    }

with help of friends ,I solve my last problem , the new problem is this , The adapter doesn't update so it doesn't add new rows to ListView. I logged and I've 30 new items in the baseAdapter here :

public void addAll(ArrayList<HashMap<String, String>> result) {
            Log.v("this",result.size()+" resultsize");
            this.list = result;
            notifyDataSetChanged();
        }

but it's not adding to listView.

could you help me to solve this problem ?

Thanks

Upvotes: 0

Views: 1147

Answers (4)

Hareshkumar Chhelana
Hareshkumar Chhelana

Reputation: 24848

You have used contactList ArrayList to showing ListView item and you will update data to contactList in doinBackground() which run another thread not in ui thread so you can not update ui data from out ui therad hence you have to take local ArrayList for doInBackground() and pass new or updated data to onPostExecute() which update this data to ui thread.

private class GetContacts extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {
    @Override
    protected ArrayList<HashMap<String, String>> doInBackground(Void... arg0) {
        Spots_tab1_json sh = new Spots_tab1_json();
        String jsonStr = sh.makeServiceCall(url + page, Spots_tab1_json.GET);

        ArrayList<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();
        if (jsonStr != null) {
            try {
                JSONObject jsonObj = new JSONObject(jsonStr);
                contacts = jsonObj.getJSONArray(TAG_CONTACTS);

                for (int i = 0; i < contacts.length(); i++) {
                    JSONObject c = contacts.getJSONObject(i);
                    String id = new String(c.getString("id").getBytes("ISO-8859-1"), "UTF-8");
                    String dates = new String(c.getString("dates").getBytes("ISO-8859-1"), "UTF-8");
                    String price = new String(c.getString("gheymat").getBytes("ISO-8859-1"), "UTF-8");
                    HashMap<String, String> contact = new HashMap<String, String>();
                    contact.put("id", id);
                    contact.put("dates", dates);
                    contact.put("price", price);
                    data.add(contact);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return data;
    }

    @Override
    protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
        super.onPostExecute(result);
        if(ladap==null){
            ladap=new ListAdapter(MainActivity.this,result);
            lv.setAdapter(ladap);
        }else{
            ladap.addAll(result);
            ladap.notifyDataSetChanged();
        }
    }
}

Upvotes: 2

PsyGik
PsyGik

Reputation: 3675

if (!isCancelled() && goterr == false) {
        ListAdapter ladap=new ListAdapter(MainActivity.this, contactList);
        lv.setAdapter(ladap);
        ladap.notifyDataSetChanged();
        //ladap.updateList(contactList);
}

is wrong.

It should be

if (!isCancelled() && goterr == false) {
        ladap.addAll(contactList);
        ladap.notifyDataSetChanged();
}

You should define your adapter only once and update the values in it accordingly. You can use various constructors to suit your requirements.

---------------------EDITED---------------------

if (!isCancelled() && goterr == false) {
            if(ladap==null){
                ladap=new ListAdapter(MainActivity.this, contactList);
                lv.setAdapter(ladap);
                ladap.addAll(contactList);

            }else{
                ladap.addAll(contactList);
}

    }

public void addAll(ArrayList<HashMap<String, String>> contactList) {
thislist.clear();       
 this.list = contactList;
        notifyDataSetChanged();
    }

Upvotes: 1

TacB0sS
TacB0sS

Reputation: 10266

OK, so if you want to create an adapter ONLY once then fine, do it when the asyc task ends, otherwise make it a member and initiate it in an onCreate or something like that.

Technically if you replace all the content of the list, then your approach is fine, replace the ArrayList, but don't forget to call adapter.notifyDataSetChanged().

BUT if you only change some of the content of the list e.g. you add new elements or remove elements, then you should perform these changes on the original ArrayList, and then call the adapter.notifyDataSetChanged().

NOTE, all calls to adapter.notifyDataSetChanged() should be done on UI Thread.

Also, from what I see, if this is the exact code you are running you should not get this error, it seemed like the error is generated from another place.

Upvotes: 1

user4182386
user4182386

Reputation:

This is wrong

 public void updateList(ArrayList<HashMap<String, String>> list) {
             this.list = list;
             notifyDataSetChanged();
        }

this is wrong too

if (!isCancelled() && goterr == false) {
            ListAdapter ladap=new ListAdapter(MainActivity.this, contactList);
            lv.setAdapter(ladap);
            ladap.notifyDataSetChanged();
            //ladap.updateList(contactList);
    }

What you can do is instead of creating a new Adapter, add data to your previous adapter that you have created above

ListAdapter ladap

Upvotes: 1

Related Questions