android -BaseAdapter不会向listView添加新项

时间:2014-10-28 06:22:20

标签: android listview android-arrayadapter android-adapter

我不知道为什么我的listView不会添加新项目。

这是代码:

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

在朋友的帮助下,我解决了我的最后一个问题,新问题是这个,适配器没有更新,所以它不会向ListView添加新行。我记录了这个baseAdapter中有30个新项目:

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

但它没有添加到listView。

你可以帮我解决这个问题吗?

谢谢

4 个答案:

答案 0 :(得分:2)

你已经使用contactList ArrayList来显示ListView项目,你将把数据更新到doinBackground()中的contactList,它运行不在ui线程中的另一个线程,这样你就不能从ura therad中更新ui数据,因此你必须使用本地ArrayList doInBackground()并将新的或更新的数据传递给onPostExecute(),它将此数据更新为ui线程。

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

答案 1 :(得分:1)

这是错误的

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

这也是错误的

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

您可以做的不是创建新的适配器,而是将数据添加到您在上面创建的上一个适配器

ListAdapter ladap

答案 2 :(得分:1)

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

错了。

应该是

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

您应该只定义一次适配器并相应地更新其中的值。 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();
    }

答案 3 :(得分:1)

好的,所以如果你想只创建一个适配器一次就好了,那么当asyc任务结束时再做,否则把它变成一个成员并在onCreate或类似的东西中启动它。

从技术上讲,如果你替换列表的所有内容,那么你的方法很好,替换ArrayList,但不要忘记调用adapter.notifyDataSetChanged()。

但如果您只更改列表的某些内容,例如你添加新元素或删除元素,然后你应该在原始ArrayList上执行这些更改,然后调用adapter.notifyDataSetChanged()。

注意,对adapter.notifyDataSetChanged()的所有调用都应该在UI Thread上完成。

另外,从我看到的情况来看,如果这是您运行的确切代码,则不应该出现此错误,似乎错误是从其他地方生成的。