我的ListView出现了这个错误:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes
。
在我的应用程序中,我有一个带有CustomAdapter的ListView。
在OnCreate方法中我有:
list = new ArrayList<FriendVO>();
mListView = (ListView) this.findViewById(R.id.listView1);
mFriendAdapter = new FriendAdapter(null);
mListView.setAdapter(mFriendAdapter);
我还有一个AsyncHttpResponseHandler,它从我的webservice获取数据以填充我的ListView。 Everthing可以正常工作。在AsyncHttpResponseHandler的onFinish()方法中,我正在更新List View的数据。
当我到达onFinish()方法时,我已经有了数据列表。
@Override
public void onFinish(){
mFriendAdapter.setData(list);
mListView.setOnItemClickListener(itemClickListener);
}
这是我的自定义适配器:
private class FriendAdapter extends BaseAdapter {
private List<FriendVO> mData;
private LayoutInflater mInflater;
public FriendAdapter(List<FriendVO> data) {
mData = data;
mInflater = FaceVsFaceActivity.this.getLayoutInflater();
}
public void setData(List<FriendVO> data) {
mData = data;
this.notifyDataSetChanged();
}
@Override
public int getCount() {
if (mData != null)
return mData.size();
else
return 0;
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
// TODO: If id is needed, change it
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
RowViewsHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.friend_row, parent, false);
holder = new RowViewsHolder(convertView);
convertView.setTag(holder); // Save inside view the holder.
} else {
holder = (RowViewsHolder) convertView.getTag();
}
FriendVO vo = mData.get(position);
holder.eventName.setText(vo.getName());
holder.eventImage.setImageResource(R.drawable.image);
return convertView;
}
}
private class RowViewsHolder {
private ImageView eventImage;
private TextView eventName;
public RowViewsHolder(View rowView) {
eventImage = (ImageView) rowView.findViewById(R.id.img_friend);
eventName = (TextView) rowView.findViewById(R.id.friend_name);
}
}
可以为此提供什么解决方案?我想我在使用列表时会出现错误(滚动,单击)并且数据正在更新。请一点帮助。
答案 0 :(得分:0)
您正在从不是UI线程的线程修改适配器,Android不喜欢它。你可以使用 调用mFriendAdapter.setData(list)的Activity.runOnUiThread()方法;打电话并避免这种例外。你需要将它包装在Runnable中。
答案 1 :(得分:0)
“所有处理都应该用这四种方法之一处理,然后调用在UI线程上运行一个新的runnable,或者在UI线程上运行的onFinish中处理”
因此,在onFinish中设置适配器不是问题。
我不喜欢将事物设置为null然后如果你不需要更改它们,那么我对你的onCreate进行了更改。另外,我建议调用notifyDataSetChanged而不是setData。试一试,让我知道会发生什么。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact_picker_main);
list = new ArrayList<FriendVO>();
mListView = (ListView) this.findViewById(R.id.listView1);
mFriendAdapter = new FriendAdapter(list);
mListView.setAdapter(mFriendAdapter);
}
@Override
public void onFinish(){
mFriendAdapter.notifyDataSetChanged();
mListView.setOnItemClickListener(itemClickListener);
}
另外,改变这个:
@Override
public int getCount() {
if (mData != null)
return mData.size();
else
return 0;
}
到此:
@Override
public int getCount() {
return mData.size();
}
你的mData永远不应为null(在最坏的情况下,它将为空,因此大小为零)如果是,则需要修复一个问题。这种空检查只会导致您不想要注意的问题。
最后。您的适配器设置为允许任何对象作为mData传递。将您的getItem从Object更改为FriendVO,以便更好地控制和保持一致性。