【问题标题】:android -BaseAdapter doesn't add new items to listViewandroid -BaseAdapter 不会向 listView 添加新项目
【发布时间】:2014-12-23 11:39:57
【问题描述】:

我不知道为什么我的 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。

你能帮我解决这个问题吗?

谢谢

【问题讨论】:

  • 异常中的第一行告诉你究竟出了什么问题。您正在修改列表的数据集。在我看来,您正在动态创建全新的适配器,而不是使用您之前创建的适配器。
  • 我认为您已经在外部声明适配器对象并检查 onPostExecute 是否为空,然后创建新实例,否则只需在适配器 updateList 方法中传递您的新数据,但您在 updateList 方法中也有更改代码,您无法设置this.list == list 而不是这个检查列表是否为空,然后创建列表的新实例并将所有数据添加到列表中,例如:list.addAll()。
  • 你能发布你的整个活动吗?有些事情没有意义
  • @LokiSinclair 感谢您的回复,我更新了我的代码,但仍然收到此错误。你能帮我一个忙,看看我的新代码。也许你能帮我解决这个烦人的问题。谢谢
  • @HareshChhelana 感谢您的回复,我更新了我的代码,但仍然收到此错误。你能帮我一个忙,看看我的新代码。也许你能帮我解决这个烦人的问题。谢谢

标签: android listview android-arrayadapter android-adapter


【解决方案1】:

您已使用contactList ArrayList 来显示ListView 项目,并且您将在doinBackground() 中将数据更新到contactList,它运行不在ui 线程中的另一个线程,因此您无法从ui 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();
        }
    }
}

【讨论】:

  • 非常感谢您的回复,我将代码更改为您所说的(我用新代码更新了我的问题)。我认为在您的帮助下,最后一个问题得到了解决,但是有一个新问题,在我调用 ladap.addAll(result); 后列表视图没有更新;我登录了,我有 30 个新项目,但它没有向 listView 添加新项目。你能帮我解决这个问题吗?
【解决方案2】:

这是错误的

 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

【讨论】:

  • 谢谢你的回复,我把你说的第一部分代码去掉,第二部分你说错了,应该换成什么?
  • 将其添加到您的适配器,然后在完成后通知您的适配器数据集已更改或数据集无效:)
  • 设置适配器后,继续使用相同的适配器,使用 ArrayAdapter 而不是 BaseAdapter 扩展您的适配器。
  • 感谢您的回复,我更新了我的代码,但仍然收到此错误。你能帮我一个忙,看看我的新代码。也许你能帮我解决这个烦人的问题。谢谢
【解决方案3】:

好的,所以如果你只想创建一个适配器就可以了,在 asyc 任务结束时执行,否则让它成为一个成员并在 onCreate 或类似的东西中启动它。

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

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

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

另外,据我所知,如果这是您正在运行的确切代码,则不应出现此错误,似乎该错误是从另一个地方生成的。

【讨论】:

  • 感谢您的回复,我更新了我的代码,但仍然收到此错误。你能帮我一个忙,看看我的新代码。也许你能帮我解决这个烦人的问题。谢谢
  • 尝试在 Activity onCreate 中创建适配器,例如这些行: ladap=new ListAdapter(MainActivity.this,result); lv.setAdapter(ladap);
  • 也可能与 AsyncTask 和内存泄漏有关,但如果没有完整的调试功能,我不能肯定
【解决方案4】:
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.

----------已编辑----------

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

【讨论】:

  • 感谢您的回复,我更新了我的代码,但仍然收到此错误。你能帮我一个忙,看看我的新代码。也许你能帮我解决这个烦人的问题。谢谢
  • thislist.clear();清除数据,我的意思是,在实现这一行之后,listview 是空的,什么都没有检索到。
  • protected Void doInBackground(Void... arg0) 什么也不返回。要获取数据,您需要从 doInBackground() 方法返回。然后使用该数据更新联系人列表视图。问题是绑定到适配器的 ArrayList 在后台线程中发生了更改。您的适配器实际上是从后台线程修改的,正如异常所建议的那样。解决方案是将其移至 UI 线程。检查@Haresh Chhelana 答案。
  • 感谢您的回复,我将代码更改为您所说的(我用新代码更新了我的问题)。我认为最后一个问题已解决,但有一个新问题,在我调用 ladap.addAll(result); 后列表视图没有更新;我登录了,我有 30 个新项目,但它没有向 listView 添加新项目。你能帮我解决这个问题吗?
猜你喜欢
  • 1970-01-01
  • 2017-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-05
  • 2020-03-23
相关资源
最近更新 更多