2014-02-10 37 views
0

我得到這個錯誤與我的ListView:ListView錯誤 - java.lang.IllegalStateException

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

在我的應用程序中,我有一個ListView與CustomAdapter。

在onCreate方法我:

list = new ArrayList<FriendVO>(); 
mListView = (ListView) this.findViewById(R.id.listView1); 
    mFriendAdapter = new FriendAdapter(null); 
    mListView.setAdapter(mFriendAdapter); 

我也有,從我的web服務中獲取數據,以填補我的ListView的AsyncHttpResponseHandler。 Everthing正常工作。在AsyncHttpResponseHandler的onFinish()方法中,我正在更新列表視圖的數據。

當我到達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

從AsyncHttpResponseHandler文檔「所有的處理應該在這4種方法中的一種,然後進行處理或者調用到UI運行線程一個新的可運行,或在onFinish處理它運行在UI線程」

所以在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不應該爲空(在最壞的情況,它會是空的,因此大小將爲零),如果是,則需要修復一個問題。這個空檢查只能導致你不想要的問題被忽視。

最後。您的適配器設置爲允許任何對象作爲mData傳遞。將您的getItem從Object更改爲FriendVO,爲您提供更好的控制和一致性。

+0

所以我做了改變。它不會給我同樣的錯誤,但現在有時它給了我另一個錯誤:java.lang.IndexOutOfBoundsException:無效的索引7,在「FriendVO vo = mData.get(position);」適配器中的大小爲0任何想法? –

+0

你可以發佈「列表」的內容以及如何創建它?如果您不想公開這麼做,我已經回覆了您在Google+上的線索,可以向我發送有關環聊的消息 – Psest328

+0

無論何時更改適配器的數據,您都應該在適配器上調用BaseAdapter.notifyDataSetChanged()。如果您不這樣做,則數據和Adapter認爲數據的內容不同,並且計數可能錯誤,從而導致ArrayOutOfBounds異常。 –

0

您正在從不是UI線程的線程修改適配器,Android不喜歡這樣。您可以使用 Activity.runOnUiThread()方法調用您的mFriendAdapter.setData(list);調用並避免此異常。您需要將其包裝在Runnable中。

+0

所以我設置啊,我完成方法我有這樣的:runOnUiThread(新的Runnable(){ \t \t \t \t \t \t \t \t \t \t \t \t \t \t @覆蓋 \t \t \t \t \t \t \t公共無效的run (){ \t \t \t \t \t \t \t \t // TODO自動生成方法存根 \t \t \t \t \t \t \t \t mFriendAdapter.setData(listado); \t \t \t \t \t \t \t \t mListView.setOnItemClickListener(itemClickListener); \t \t \t \t \t \t \t} \t \t \t \t \t \t});但它仍然不起作用。有時它給了我同樣的錯誤,有時它給了我一個IndexOutOfbondsException。感謝您的幫助。 –