2014-04-15 25 views
0

使用我的自定義適配器 - 我正在使用AsyncTask填充listiewdoInBackground更新用於自定義適配器的ArrayList。該onProgressUpdate調用adapter.notifyDataSetChanged();自定義適配器更改時滾動的簡單修復程序?

當加載了很多文件,我希望UI來響應,但是當你嘗試仍然被填充列表時滾動,我得到這個錯誤:

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. 


@Override 
     protected Boolean doInBackground(DbxFileSystem... params) { 
      //Opens thumbnails for each image contained in the dropbox folder 
      try { 
       DbxFileSystem fileSystem = params[0]; 
       numFiles = fileSystem.listFolder(currentPath).size(); 
       for (DbxFileInfo fileInfo: fileSystem.listFolder(currentPath)) { 
        String filename = fileInfo.path.getName(); 


        try{ 
         if(!fileInfo.isFolder) 
         { 
          Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); 
          pix.add(image); 
          paths.add(fileInfo.path); 
          publishProgress(1); //use this to update the ListView 
         } 
         else 
         { 
          //must be a folder if it has no thumb, so add folder icon 
          Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.dbfolder); 
          pix.add(image); 
          paths.add(fileInfo.path); 
          publishProgress(1); 


         } 

        catch(Exception e) 
        { 
         e.printStackTrace(); 
        } 
        System.gc(); 
       } 

      } 
      catch (Exception e) { 
       e.printStackTrace(); 
       return false; 
      } finally { 
      } 
      return true; 
     } 

     @Override 
     protected void onProgressUpdate(Integer...progress) { 

      if(pix.size()==1) // //not ideal but works for now, only bind the adapter if its the first time we have looped through. 
      { 
      adapter = new ImageAdapter(getApplicationContext(), pix, paths, numFiles); 
      lstView.setAdapter(adapter); 
      } 

      adapter.notifyDataSetChanged(); 
      lstView.requestLayout(); 
      super.onProgressUpdate(progress); 
     } 

任何人都可以看到這裏有什麼問題嗎?我能做些什麼來阻止它? 我最初使用的是一個進度條,並且只在所有加載完成後才顯示填充內容,但我更願意顯示增量加載並讓用戶滾動,即使加載內容。

p.s.我發現這是一個普遍的問題,並且已經閱讀了幾個類似的問題,但我仍然無法弄清楚我需要改變什麼。

回答

0

你的適配器有PIX,numFiles並作爲數據源,路徑和因爲你是doInBackground修改這些藏品在()這是在非UI線程運行你得到這個例外。

new ImageAdapter(getApplicationContext(), pix, paths, numFiles);通過那些收集通過參考

+0

謝謝我會試試這個 - 這是否意味着當適配器更新時列表會自動跳回頂部? – user3437721

+0

所以在我的onProgressUpdate我應該只有:adapter = new ImageAdapter(getApplicationContext(),pix,paths,numFiles); lstView.setAdapter(adapter); – user3437721

+0

不,問題在於你要將項目添加到線程中的pix和路徑集合中。在onProgressUpdate中創建適配器不會改變您從非UI線程修改適配器數據的事實。 你不能這樣做。您應該等到doinBackground完成後,將您的適配器填充到onPostExecute()中,然後再調用notifyDatasetChanged()。這就是使用asyncTask的方式。 – JimmyVanBraun