2011-12-30 93 views
2

我創建了一個應用程序,允許用戶在外部存儲上創建相冊(文件夾)。現在我試圖從所述目錄中檢索圖像並將其顯示在GridView中。我使用AsyncTask遍歷使用listFiles()的文件目錄,然後創建一個位圖,一旦我抓住每個圖像,回收它,然後再次使用它。我的問題是,我的GridView沒有顯示任何內容。我已經設置了幾個日誌中斷,LogCat顯示迭代確實發生並且圖像被檢索。這導致我認爲我在我的Adapter類中的某處發生了錯誤,它將位圖綁定到了網格,可能在getView中?或者,也許我錯了。任何幫助我做錯了什麼?我試圖儘可能地對代碼進行評論,而我忽略了不必要的部分。謝謝從GridView中的SD卡目錄加載圖像

public class AlbumGridView extends Activity implements OnItemClickListener { 

private GridView sdcardImages; 
private ImageAdapter imageAdapter; 

private Display display; 

private Bitmap bitmap; 
private Bitmap b; 

File[] imageList; 
private static final String TAG = "AlbumGridView"; 
String path; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 
    setContentView(R.layout.album_view); 

    //display = 
    //((Object) getSystemService(Context.WINDOW_SERVICE))).getDefaultDisplay(); 

    path = getIntent().getStringExtra("key"); 
    Toast.makeText(this, path, Toast.LENGTH_SHORT).show(); 
    setupViews(); 
    setProgressBarIndeterminateVisibility(true); 
    loadImages(); 



} 

protected void onDestroy() { 
    super.onDestroy(); 
    final GridView grid = sdcardImages; 
    final int count = grid.getCount(); 
    ImageView v = null; 
    for (int i = 0; i < count; i++) { 
     v = (ImageView) grid.getChildAt(i); 
     ((BitmapDrawable) v.getDrawable()).setCallback(null); 
    } 
} 

// Set up the GridView 

private void setupViews() { 
    sdcardImages = (GridView) findViewById(R.id.gvAlbumView); 
    // sdcardImages.setNumColumns(display.getWidth()/95); 
    sdcardImages.setClipToPadding(false); 
    sdcardImages.setOnItemClickListener(AlbumGridView.this); 
    imageAdapter = new ImageAdapter(getApplicationContext()); 
    // imageAdapter.setImageList(path); 
    sdcardImages.setAdapter(imageAdapter); 
} 

private void addImage(LoadedImage... value) { 
    for (LoadedImage image : value) { 
     imageAdapter.addPhoto(image); 
     imageAdapter.notifyDataSetChanged(); 
    } 
} 

// Save Bitmap images to a list and return that list 
@Override 
public Object onRetainNonConfigurationInstance() { 
    final GridView grid = sdcardImages; 
    final int count = grid.getChildCount(); 
    final LoadedImage[] list = new LoadedImage[count]; 

    for (int i = 0; i < count; i++) { 
     final ImageView v = (ImageView) grid.getChildAt(i); 
     list[i] = new LoadedImage(
       ((BitmapDrawable) v.getDrawable()).getBitmap()); 
    } 

    return list; 
} 

private void loadImages() { 
    // TODO Auto-generated method stub 
    final Object data = getLastNonConfigurationInstance(); 
    if (data == null) { 
     new LoadImagesFromSDCard().execute(); 
    } else { 
     final LoadedImage[] photos = (LoadedImage[]) data; 
     if (photos.length == 0) { 
      new LoadImagesFromSDCard().execute(); 
     } 
     for (LoadedImage photo : photos) { 
      addImage(photo); 
     } 
    } 
} 

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { 
    // TODO Auto-generated method stub 

} 

/---------------------------------------- ---------------------------------------------/

//Adapter for the GridView 

public class ImageAdapter extends BaseAdapter { 

    private Context mContext; 
    private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>(); 

    private String path; 
    private Bitmap bitmap; 

    public ImageAdapter(Context context) { 
     mContext = context; 
    } 

    public void addPhoto(LoadedImage photo) { 
     photos.add(photo); 
    } 

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

    public Object getItem(int position) { 
     return photos.get(position); 
    } 

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

    /* 
    * public File[] setImageList(String path) { 
    * 
    * //this.path = path; //this.imageList = imageList; //File imagesDir = 
    * new File(path); //imageList = imagesDir.listFiles(); 
    * 
    * File imagesDir = new File(path); imageList = imagesDir.listFiles(); 
    * for (File image : imageList) try { bitmap = 
    * BitmapFactory.decodeStream(image.toURL().openStream()); //use bitmap 
    * and recycle afterwards LoadedImage lm = new LoadedImage(bitmap); 
    * this.addPhoto(lm); bitmap.recycle(); 
    * 
    * } catch (IOException e) { e.printStackTrace(); } return imageList; 
    * 
    * } 
    */ 

    public View getView(int position, View convertView, ViewGroup parent) { 
     final ImageView imageView; 
     if (convertView == null) { 
      imageView = new ImageView(mContext); 
     } else { 
      imageView = (ImageView) convertView; 
     } 
     imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); 
     imageView.setPadding(2, 2, 2, 2); 
     // imageView.setImageBitmap(photos.get(position).getBitmap()); 
     try { 
      imageView 
        .setImageBitmap(BitmapFactory 
          .decodeStream(imageList[position].toURL() 
            .openStream())); 
     } catch (MalformedURLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return imageView; 
    } 
} 

/*-------------------------------------------------------------------------*/ 

//AsyncTask to get the images 

class LoadImagesFromSDCard extends AsyncTask<Object, LoadedImage, Object> { 

    @Override 
    protected Object doInBackground(Object... arg0) { 
     // Load images from SD card in Background 
     // Display each image on the screen 

     File imagesDir = new File(path); 
     imageList = imagesDir.listFiles(); 

     for (File image : imageList) 

      try { 

       if (bitmap != null) { 
        bitmap.recycle(); 
        bitmap = null; 
       } 
       bitmap = BitmapFactory.decodeStream(image.toURL() 
         .openStream()); 
       Log.e(TAG, "Grabbed Image " + image.getName()); 
       // use bitmap then recycle after 

       LoadedImage lm = new LoadedImage(bitmap); 
       // addImage(lm); 
       // imageAdapter.addPhoto(lm); 
       // imageAdapter.setImageList(path); 
       // imageAdapter.addPhoto(lm); 
       // imageAdapter.setImageList(path); 
       // bitmap.recycle(); 
       // addImage(lm); 
       // imageAdapter.addPhoto(lm); 
       Log.e(TAG, "Added Image " + lm.toString()); 

       // imageAdapter.setImageList(path); 
       addImage(lm); 

       // bitmap.recycle(); 

       // bitmap.recycle(); 

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

     return null; 
    } 
+0

沒關係。我想通了:) – 2012-01-06 04:03:10

+0

也許你應該用解決方案更新你的問題,以防其他人遇到同樣的問題,並找到這篇文章。 – eightx2 2012-02-07 13:29:27

+0

問題是什麼? – jramirez 2012-04-10 21:58:36

回答

1

這裏的解決方案順便說一句,抱歉花了這麼長時間,我沒有意識到其他人正在等待答案。抱歉。相關代碼如下。

這是AsyncTask,它將查詢設備的MediaStore並檢索所有照片。請注意,這是檢索縮略圖而不是全尺寸圖像,更具體地說是MICRO_KIND。還有一個Thumbnail.MINI_KIND。

/*----------------------------ASYNC TASK TO LOAD THE  PHOTOS--------------------------------------------------------*/ 

public class LoadPhotos extends AsyncTask<Object, Object, Object> { 

    @Override 
    protected Object doInBackground(Object... params) { 
     try { 
      final String[] columns = { MediaStore.Images.Media._ID }; 
      final String orderBy = MediaStore.Images.Media._ID; 

      Cursor imagecursor = managedQuery(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, 
        null, null, orderBy); 

      int image_column_index = imagecursor 
        .getColumnIndex(MediaStore.Images.Media._ID); 

      AllPhotosActivity.count = imagecursor.getCount(); 
      AllPhotosActivity.windows = new Bitmap[AllPhotosActivity.count]; 

      for (int i = 0; i < AllPhotosActivity.count; i++) { 
       imagecursor.moveToPosition(i); 
       // i = index; 
       int id = imagecursor.getInt(image_column_index); 
       windows[i] = MediaStore.Images.Thumbnails.getThumbnail(
         getApplicationContext().getContentResolver(), id, 
         MediaStore.Images.Thumbnails.MICRO_KIND, null); 
      } 

      imagecursor.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      Log.d("AllPhotosActivity", 
        "Error occured while fetching all photos on device."); 
     } 
     return null; 

    } 

    @Override 
    protected void onPostExecute(Object result) { 
     // TODO Auto-generated method stub 
     super.onPostExecute(result); 
     Handler mHandler = new Handler(); 

     mHandler.post(new Runnable() { 

      public void run() { 

       pd.dismiss(); 
       // imageAdapter.notifyDataSetChanged(); 
       // sdcardImages.setAdapter(imageAdapter); 

      } 

     }); 

     // pd.dismiss(); 
     imagegrid.setAdapter(imageAdapter); 
     // pd.dismiss(); 

    } 

    @Override 
    protected void onProgressUpdate(Object... values) { 
     // TODO Auto-generated method stub 
     super.onProgressUpdate(values); 
    } 

} 

下面是GridView的適配器,它將綁定縮略圖到gridview。我的問題只是在我的ImageAdapter的getView方法,注意我設置我的ImageView資源從我稱爲Windows的Bitmaps數組的不同索引。

public class ImageAdapter extends BaseAdapter { 
    private Context mContext; 

    public ImageAdapter(Context c) { 
     mContext = c; 
    } 

    public Object getItem(int position) { 
     // TODO Auto-generated method stub 
     return position; 
    } 

    public long getItemId(int position) { 
     // TODO Auto-generated method stub 
     return position; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     ImageView i = (ImageView) convertView; 
     if (i != null) { 
      i.setImageBitmap(windows[position]); 
     } else { 
      i = new ImageView(mContext.getApplicationContext()); 
      // i.setPadding(3, 3, 3, 3); 
      // i.setScaleType(ImageView.ScaleType.FIT_CENTER); 
      i.setAdjustViewBounds(true); 
      // i.setMaxHeight(200); 
      // i.setMaxWidth(200); 
      i.setPadding(3, 3, 3, 3); 
      i.setLayoutParams(new GridView.LayoutParams(92, 92)); 
      i.setImageBitmap(windows[position]); 

     } 
     return i; 
    } 

    public int getCount() { 
     // TODO Auto-generated method stub 
     return count; 
    } 
}