0

我一直在嘗試更新我的圖片GridView。
只有當我再次設置適配器時,圖像纔會更新。再次設置適配器會使我的活動回滾到頂端,我儘量避免這種情況。圖片GridView不會失效

下面是一些代碼:

private class LoadImagesTask extends AsyncTask<Object,Void, Object> { 
private ImageAdapter imageAdapter; 
private ArrayList<Integer> idsArray; 
@Override 
protected void onPreExecute() { 
    imageAdapter = new ImageAdapter(getApplicationContext()); 
    Bitmap bmap = BitmapFactory.decodeResource(getResources(), 
      R.drawable.locked_image); 
    idsArray = dbHelper.getPicturesIdsByAlbumId(1); 
    for(int i = 0;i<idsArray.size();i++){ 
     imageAdapter.bitmaps.add(bmap); 
    } 

    gridView.setAdapter(imageAdapter); 
} 
@Override 
protected Void doInBackground(Object... arg) { 

    for(int i = 0;i<idsArray.size();i++){ 
     byte[] data = dbHelper.getPictureById(idsArray.get(i)).littlePicBytes; 
     imageAdapter.bitmaps.set(i, BitmapFactory.decodeByteArray(data, 0, data.length)); 
     publishProgress(); //********** This line calls onProgressUpdate() ********* 
    } 
    return null; 

} 

現在,此代碼更新的觀點:

@Override 
    protected void onProgressUpdate(Void... params) { 
    gridView.setAdapter(imageAdapter); 
    } 

但這並不:

@Override 
    protected void onProgressUpdate(Void... params) { 
    imageAdapter.notifyDataSetChanged(); 
    gridView.invalidateViews(); 
    } 

可能是什麼不是這個原因更新我的觀點?謝謝!

編輯:的ImageAdapter代碼:

公共類ImageAdapter延伸BaseAdapter { 私有上下文mContext; public ArrayList bitmaps = new ArrayList();公共ImageAdapter(Context c){ mContext = c;

} 

public int getCount() { 
    return bitmaps.size(); 
} 

public Object getItem(int position) { 
    return position; 
} 

public long getItemId(int position) { 
    return position; 
} 

// create a new ImageView for each item referenced by the Adapter 
public View getView(int position, View convertView, ViewGroup parent) { 
    LayoutInflater inflater = (LayoutInflater) mContext 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

     View gridView; 

     if (convertView == null) { 

      gridView = new View(mContext); 

      // get layout from mobile.xml 
      gridView = inflater.inflate(R.layout.image_adapter, null); 

      // set image based on selected text 
      ImageView imageView = (ImageView) gridView 
        .findViewById(R.id.imageView); 
      imageView.setImageBitmap(bitmaps.get(position)); 
     } 
      else{ 
       gridView = (View) convertView; 
      } 
     return gridView; 
} 

}

+0

可以請你告訴適配器本身的代碼嗎?順便說一句,調用notifyDataSetChanged應該足夠了。您也可以僅更新所需的視圖,而不是使所有項目無效。 –

+0

@androiddeveloper使用ImageAdapter代碼編輯我的帖子。我意識到我可以只更新所需的視圖,但它無法正常工作:) – idish

+0

你getView沒有正確實現。請閱讀關於它的更多信息,並觀看「listView的世界」(從adapterView擴展gridview和listview,所以它們的提示對於兩者都是相同的):http://www.google.com/events/io/2010/sessions /world-of-listview-android.html。我現在要寫下代碼中的錯誤,並提供如何糾正錯誤,但請仔細閱讀。 –

回答

1

你在你的代碼的2個主要問題:

  1. 在doInBackground

    ,您更改適配器,這不是線程安全運行的數據,自適配器可能會在您更改數據時從數據中讀取數據。我正在談論這條線:

    imageAdapter.bitmaps.set(i, BitmapFactory.decodeByteArray(data, 0, data.length)); 
    

    相反,您應該只在UI線程上更新其數據,例如在onProgressUpdate中。

  2. 在getView中,您已經錯誤地實現了它。當convertView不爲null時,你永遠不會更新imageView的內容。它應該是什麼樣子是一樣的東西:

public View getView(int position, View convertView, ViewGroup parent) 
    { 
    View rootView=convertView; 
    ViewHolder holder; 
    if (rootView != null) 
    holder=(ViewHolder) rootView.getTag(); 
    else 
    { 
    rootView = inflater.inflate(R.layout.image_adapter, null,false); 
    holder = new ViewHolder(); 
    holder.imageView = (ImageView) rootView.findViewById(R.id.imageView); 
    rootView.setTag(holder); 
    } 
    holder.imageView.setImageBitmap(getItem(position)); 
    return rootView; 
    } 


private Bitmap getItem(final int position) 
    { 
    return bitmaps.get(position); 
    }  

private static class ViewHolder 
    { 
    ImageView imageView; 
    } 
+0

太棒了!完美的作品。非常感謝你。 – idish

+0

它運行良好,現在我只需要調用notifydatasetchanged(),但gridview的佈局仍會在更新時滾動回頂端。我試圖保存滾動的位置和設置再次選擇,但滾動很漂亮,並不平滑。 – idish

+0

這裏是onProgressUpdate的新代碼:http://pastebin.com/CQLckaVh – idish