Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android-notifyDataSetChanged doesn't work on BaseAdapter

i've a listview on my activity , when I reach the end of listview , it calls async and it getting new data using json . this is the async and baseAdaper codes :

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

I logged here , when I reach the end of listView , it calls addAll and it returns new 30 items buy it doesn't added to listview , I don't know why .

like image 735
Navid Abutorab Avatar asked Nov 08 '14 04:11

Navid Abutorab


People also ask

How does notifyDataSetChanged work on Android?

This android function notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself. You can use notifyDataSetChanged ArrayAdapter, but it only works if you use the add(), insert(), remove(), and clear() on the Adapter.

What happens when we call notifyDataSetChanged?

notifyDataSetChanged. Notify any registered observers that the data set has changed. There are two different classes of data change events, item changes and structural changes. Item changes are when a single item has its data updated but no positional changes have occurred.

How do I use notifyDataSetChanged in Kotlin?

How do I use notifyDataSetChanged in Kotlin? To refresh the ListView in Android, call notifyDataSetChanged() method on the Adapter that has been set with the ListView. Also note that the method notifyDataSetChanged() has to be called on UI thread.

When you're using a BaseAdapter how many method must be implemented?

Adapter interface defines 10 methods that must be implemented by the developer. BaseAdapter is provided as a convenience to Android developers.


2 Answers

First of all you have already notify your list view when you call addAll() so this code no longer required please remove from your code :

ladap.notifyDataSetChanged();

Add new data to list view data holder instead of assign new data to list view data holder :

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

Replace with :

public void addAll(ArrayList<HashMap<String, String>> result) {
    Log.v("this",result.size()+" resultsize");
    if(list==null){
      list = new ArrayList<HashMap<String, String>>();
    }
    list.addAll(result)
    notifyDataSetChanged();
}
like image 108
Haresh Chhelana Avatar answered Nov 11 '22 12:11

Haresh Chhelana


Try to change this :

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

To :

public void addAll(ArrayList<HashMap<String, String>> result) {
    Log.v("this",result.size()+" resultsize");
    for(int i = 0;i < result.size(); i++)
       list.add(result.get(i));
    //notifyDataSetChanged(); //no need to call again here
}

The point is, i think this.list = result; will delete the old items before adding a new item.

like image 43
Blaze Tama Avatar answered Nov 11 '22 11:11

Blaze Tama