android -BaseAdapter 不会向 listView 添加新项目
Posted
技术标签:
【中文标题】android -BaseAdapter 不会向 listView 添加新项目【英文标题】:android -BaseAdapter doesn't add new items to 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 感谢您的回复,我更新了我的代码,但仍然收到此错误。你能帮我一个忙,看看我的新代码。也许你能帮我解决这个烦人的问题。谢谢 【参考方案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 扩展您的适配器。 see this 2.3. ListView example with ArrayAdapter 感谢您的回复,我更新了我的代码,但仍然收到此错误。你能帮我一个忙,看看我的新代码。也许你能帮我解决这个烦人的问题。谢谢【参考方案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 添加新项目。你能帮我解决这个问题吗?以上是关于android -BaseAdapter 不会向 listView 添加新项目的主要内容,如果未能解决你的问题,请参考以下文章
Android:PagerAdapter 删除最后一个视图,因此您无法向左滑动
WearableListenerService onMessageReceived 不会被解雇 [android wear]